Entity Framework Code First-метод No Detach() в DbContext
Мне интересно, почему нет метода отсоединения на объекте DbContext, как есть для ObjectContext. Я могу только предположить, что это упущение было преднамеренным, но мне трудно понять, почему. Мне нужно иметь возможность отсоединять и повторно присоединять объекты (для размещения в кэше в ASP.NET проект, например). Однако, поскольку я не могу отсоединить сущность, когда я пытаюсь присоединить сущность, которая была связана с предыдущим контекстом, я получаю "объект сущности не может ссылаться на несколько экземпляров IEntityChangeTracker" исключение.
что здесь за руководство? Я что-то упустил?
4 ответа:
для людей, которые могут наткнуться на этот вопрос, начиная с CTP5 вам теперь нужно написать
((IObjectContextAdapter)context).ObjectContext
для того, чтобы добраться до ObjectContext.
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; } ... }
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 решила "отсоединить слишком передовые технологии и должны быть скрыты". IMHO человек, который изобрел это, должен быть застрелен - потому что если вы добавляете совершенно новую сущность, в противном случае трудно просто удалить ее, не совершая изменений в db (вы можете манипулировать DbEntityEntry, но это другая история).
редактировать 4 года позже:
С ef6 в (Я как-то пропустил EF5 :) ) вам не нужно
detach()
больше, потому что удаление недавно добавленной записи не генерируетdelete from [table] where [Id] = 0
как в EF4 - вы можете просто позвонитьmySet.Remove(myFreshlyCreatedAndAddedEntity)
и все будет хорошо.
Я обычно расширяю базовый класс (наследует от DbContext) со свойством:
public class MyDbContext : DbContext { public ObjectContext ThisObjectContext { get { return ((IObjectContextAdapter)this).ObjectContext; } } }
позже вы можете использовать это свойство для различных полезных вещей ... как отсоединить :)