Ответ 1
Для людей, которые могут наткнуться на этот вопрос, с CTP5 вам теперь нужно написать
((IObjectContextAdapter)context).ObjectContext
чтобы перейти в ObjectContext.
Мне интересно, почему не существует метода Detach для объекта DbContext, как для ObjectContext. Я могу только предположить, что это упущение было преднамеренным, но мне трудно понять, почему. Мне нужно иметь возможность отсоединять и повторно присоединять объекты (например, для кластеризации в проекте ASP.NET). Однако, поскольку я не могу отсоединить объект, когда я пытаюсь подключить объект, который был связан с предыдущим контекстом, я получаю "Объект сущности не может ссылаться на несколько экземпляров исключения IEntityChangeTracker".
Какое руководство здесь? Я что-то пропустил?
Для людей, которые могут наткнуться на этот вопрос, с 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 решила, что "Detach - слишком передовая технология и должна быть скрыта". ИМХО человек, который изобрел это, должен быть расстрелян, потому что, если вы добавите новый объект, иначе просто удалить его, не внося изменений в db (вы можете манипулировать с помощью DbEntityEntry, но это другая история).
С 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;
}
}
}
позже вы можете использовать это свойство для множества полезных вещей... например, Detach:)