我想知道爲什麼DbContext對象上沒有Detach方法,就像ObjectContext一樣。我只能假定這種疏忽是故意的,但我很難弄清楚爲什麼。我需要能夠分離和重新連接實體(例如,將緩存放入ASP.NET項目中)。然而,由於我不能分離一個實體,當我嘗試附加一個與前一個上下文關聯的實體時,我得到了「一個實體對象不能被IEntityChangeTracker的多個實例引用」異常。實體框架代碼優先 - DbContext上沒有Detach()方法
這裏有什麼指導?我錯過了什麼嗎?
我想知道爲什麼DbContext對象上沒有Detach方法,就像ObjectContext一樣。我只能假定這種疏忽是故意的,但我很難弄清楚爲什麼。我需要能夠分離和重新連接實體(例如,將緩存放入ASP.NET項目中)。然而,由於我不能分離一個實體,當我嘗試附加一個與前一個上下文關聯的實體時,我得到了「一個實體對象不能被IEntityChangeTracker的多個實例引用」異常。實體框架代碼優先 - DbContext上沒有Detach()方法
這裏有什麼指導?我錯過了什麼嗎?
對於人就這個問題可能會跌倒,如您現在需要編寫CTP5
((IObjectContextAdapter)context).ObjectContext
爲了得到ObjectContext。
+1另外你需要引用System.Data.Entity – Pandincus 2011-03-05 18:23:32
+1清潔,優雅,一個班輪,我喜歡它也想拋出,在這裏找到的接口具體是:System.Data.Entity.Infrastructure.IObjectContextAdapter和是像Pandincus指出的你還必須參考System.Data.Entity。 – dyslexicanaboko 2013-02-25 22:56:21
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; }
...
}
@Stacker這不是答案,因爲它需要在上面選定的答案中概述的轉換,即'DbContext'實現了'IObjectContextAdapter',它給了它'ObjectContext'屬性,它是結合2個答案給出了@ splite的答案,低於 – eudaimos 2012-11-19 19:07:07
ChangeObjectState是非常懶惰的,它使用的「線性算法與演員」,這是...排序...你知道... Reeeeally壞 – 2013-04-02 07:43:25
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);
}
}
微軟決定 「拆離太先進的技術,應該被隱藏」。恕我直言,誰發明了這個人應該被槍殺 - 因爲如果你添加全新的實體,否則很難刪除它沒有改變數據庫(你可以用DbEntityEntry操作,但這是另一回事)。
隨着EF6(我莫名其妙地跳過EF5 :))你不需要再detach()
,becouse除去新加入的條目不產生delete from [table] where [Id] = 0
在EF4 - 你可以叫mySet.Remove(myFreshlyCreatedAndAddedEntity)
和一切都會好起來的。
shot?誰需要該功能呢?:P – quetzalcoatl 2013-02-12 21:32:18
@quetzalcoatl:'var context = ...; var poco = new Poco(); context.Add(POCO); context.Remove(poco);'<---拋出異常,因爲你必須分離它,而不是刪除 - 嘿,分離隱藏... – 2013-03-29 10:12:12
(5分鐘編輯不見了,sry :))那時我是如此生氣......當你製作Windows應用程序時,你必須有一些方法來「取消創建新的,可能不完整的條目,但保持UoW上下文」......我們擺脫整個EF順便說一句,並編寫我們自己的ORM:沒有辦法利用延遲加載(我有一堆的發票,我不能加載每個InvoiceItem在單一「InvoiceId在(xxyy)」查詢 - 包括沒有工作方式我們預期),更大的存儲庫sooooo懶(線性(! )在每次執行之前搜索,wtf ...),爲100多個poco類型創建代理需要太多時間,等等...... – 2013-03-29 10:26:15
我通常與物業擴展基類(從繼承的DbContext):
public class MyDbContext : DbContext
{
public ObjectContext ThisObjectContext
{
get
{
return ((IObjectContextAdapter)this).ObjectContext;
}
}
}
後,你可以使用該屬性爲各種有用的東西......像拆離:)
有沒有人有什麼要說的:「這裏有什麼指導?我錯過了什麼?」就我個人而言,我只想在使用Detach的同時尋找解決方案從上下文中讀取實體,然後保存從UI返回的實例。這給了我「在ObjectStateManager中已經存在一個具有相同鍵的對象。ObjectStateManager不能使用同一個鍵來追蹤多個對象。「 – 2013-03-24 15:06:44