Entity Framework Code First - нет метода Detach () в DbContext - PullRequest
62 голосов
/ 12 ноября 2010

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

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

Ответы [ 4 ]

85 голосов
/ 08 декабря 2010

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

((IObjectContextAdapter)context).ObjectContext

чтобы добраться до ObjectContext.

37 голосов
/ 12 ноября 2010

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; }
    ...
}
16 голосов
/ 31 мая 2011

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 решила: «Отделить - это слишком продвинутая технология, и ее следует скрывать». ИМХО, человек, который изобрел это, должен быть застрелен - потому что, если вы добавляете совершенно новую сущность, в противном случае трудно просто удалить ее без внесения изменений в db (вы можете манипулировать с помощью DbEntityEntry, но это другая история).

Изменить 4 года спустя:

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

7 голосов
/ 19 февраля 2014

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...