Подтвердить что ты не робот

Entity Framework Code First - Нет метода Detach() в DbContext

Мне интересно, почему не существует метода Detach для объекта DbContext, как для ObjectContext. Я могу только предположить, что это упущение было преднамеренным, но мне трудно понять, почему. Мне нужно иметь возможность отсоединять и повторно присоединять объекты (например, для кластеризации в проекте ASP.NET). Однако, поскольку я не могу отсоединить объект, когда я пытаюсь подключить объект, который был связан с предыдущим контекстом, я получаю "Объект сущности не может ссылаться на несколько экземпляров исключения IEntityChangeTracker".

Какое руководство здесь? Я что-то пропустил?

4b9b3361

Ответ 1

Для людей, которые могут наткнуться на этот вопрос, с CTP5 вам теперь нужно написать

((IObjectContextAdapter)context).ObjectContext

чтобы перейти в ObjectContext.

Ответ 2

DbContext использует объект ObjectContext внутри, а команда EF делает это доступным как защищенное свойство на случай, если вам когда-либо понадобится перейти к API нижнего уровня, и звучит так, как это имеет место здесь, поэтому вы можете использовать или раскрывать требуемые функции из производного DbContext:

public class YourContext : DbContext 
{
    public void Detach(object entity) 
    {
        ObjectContext.Detach(entity);            
    }
}

Затем вы можете вызвать этот метод из своего контроллера, чтобы отсоединить объект.

В качестве альтернативы вы можете изменить его, чтобы даже иметь более богатый API:

public class YourContext : DbContext
{
    public void ChangeObjectState(object entity, EntityState entityState)
    {
        ObjectContext.ObjectStateManager.ChangeObjectState(entity, entityState);
    }
}

Вот как выглядит DbContext из метаданных:

public class DbContext : IDisposable 
{      
    protected System.Data.Objects.ObjectContext ObjectContext { get; }
    ...
}

Ответ 3

EF: CF 4.1 RC1 и EF: CF 4.1 RTW имеют тот же явно реализованный IObjectContextAdapter:

public static class DbContextExtensions
{
    public static void Detach(this System.Data.Entity.DbContext context, object entity)
    {
         ((System.Data.Entity.Infrastructure.IObjectContextAdapter)context).ObjectContext.Detach(entity);
    }
}

Microsoft решила, что "Detach - слишком передовая технология и должна быть скрыта". ИМХО человек, который изобрел это, должен быть расстрелян, потому что, если вы добавите новый объект, иначе просто удалить его, не внося изменений в db (вы можете манипулировать с помощью DbEntityEntry, но это другая история).

Редактировать 4 года спустя:

С EF6 (я как-то пропустил EF5:)) вам больше не нужно detach(), потому что удаление только что добавленной записи не генерирует delete from [table] where [Id] = 0, как в EF4 - вы можете просто вызвать mySet.Remove(myFreshlyCreatedAndAddedEntity) и все будет хорошо.

Ответ 4

Я обычно расширяю базовый класс (наследует от DbContext) со свойством:

public class MyDbContext : DbContext
{
    public ObjectContext ThisObjectContext
    {
        get
        {
            return ((IObjectContextAdapter)this).ObjectContext;
        }
    }
}

позже вы можете использовать это свойство для множества полезных вещей... например, Detach:)