2012-02-29 158 views
23

當我想要實際的實體類時,我遇到了實體框架返回代理的問題。我第一次運行代碼時,所有代碼都可以正常運行(無代理),但每次迭代後,我的一個DbSets總是返回代理,而不是實際類型。爲什麼EF返回一個代理類而不是實際的實體?

我在每次迭代後處理上下文,所以我不明白爲什麼第一次通過它,每次都不行。

我的代碼在這一行上失敗。我所有的POCO都有Table屬性集,但是因爲它返回的是代理類,所以沒有表屬性。

TableAttribute attrib = (TableAttribute)attributes.Single(); 

DbContext中存在一些幕後靜態魔法,它是在我銷燬該對象後生活的嗎?

我用移動我的對象到內存以下

MajorClasses = ctx.MajorClasses.ToArray(); 

我也試過

MajorClasses = ctx.MajorClasses.AsNoTracking().ToArray(); 

在我OnModelCreating,我有以下設置

base.Configuration.ProxyCreationEnabled = false; 
      base.Configuration.LazyLoadingEnabled = false; 

回答

38

您可以將ObjectContext.ContextOptions.ProxyCreationEnabled設置爲false。這會阻止你使用一些EFs的花式功能,例如延遲加載,我相信改變跟蹤。

就你的應用程序而言,它應該能夠像代表它們的類型一樣對待代理。你有什麼具體問題嗎?

編輯

我們有需要的POCO類型,而不是代理類型一些代碼,我們下面來檢測,如果當前類型是代理。

if (entityType.BaseType != null && entityType.Namespace == "System.Data.Entity.DynamicProxies") 
{ 
    entityType = entityType.BaseType; 
} 
+0

我在我的問題中增加了更多細節。我確實有這個設置集,沒有我的應用程序不能像POCO那樣處理代理。 – 2012-02-29 15:25:29

+0

它在更新的問題。我反映了從中獲取屬性的類。 – 2012-02-29 15:27:43

+0

@ MalcolmO'Hare我已經發布了我們用來從代理類型獲取POCO類型的代碼。 – cadrell0 2012-02-29 15:31:24

2

默認情況下,EF用途Change Tracking並使用所有實體的內存中緩存。使用EF時可以使用不同的合併選項。默認情況下,EF 4.1設置爲AppendOnly Merge Option。據我所知,這意味着如果你已經查詢過一個實體,隨後的查詢將從緩存中獲取該實體(如果在數據庫中沒有檢測到更改)。所以你可能會看到緩存實體回來。

在EF 4.1中,您可以使用NoTracking合併選項。這將進入每個電話的數據庫。

+0

在我的節目的每一次迭代(其輪詢數據庫,當一個記錄插入就在另一個數據庫工作)我創建了一個新的環境和我的所有數據加載到內存中。當我所有的工作完成後,所有加載的數據+上下文都會被處理掉。如果我運行兩次相同的導出,第二次運行一些記錄將作爲代理返回,這在第一次運行時不會發生。此外我現在使用4.3(升級,看看它是否解決了問題)。 – 2012-02-29 15:14:08

+0

是的,這聽起來很奇怪,你會得到一個代理對象的基礎上。不過,您可以設置爲NoTracking來排除緩存。 – 2012-02-29 15:16:11

+1

@ MalcolmO'Hare代理是否是其他實體的虛擬屬性?也許你只是看到EF延遲加載。如果您不使用(加載)設置爲虛擬的實體,則它可能會顯示爲代理。 – 2012-02-29 15:16:57

6

要在實體框架5關閉代理的創作,你可以使用下面的,

_dbContext.Configuration.ProxyCreationEnabled = false; 

只需設置該屬性使用上下文來提取數據之前一次。

1

在EF 6.1.3您可以使用

using (var context = new BloggingContext()) { 
    var blog = context.Blogs.Find(1); 
    var entityType = ObjectContext.GetObjectType(blog.GetType()); 
} 

注意得到正確的類型,如果傳遞給GetObjectType類型是實體類型的實例,它是不是一個代理類型,那麼類型實體仍然返回。這意味着您可以始終使用此方法獲取實際的實體類型,而無需其他任何檢查來查看類型是否爲代理類型。

MSDN

+2

他想要的是實際的實體,而不是它的類型。 – Tito 2017-07-17 08:22:01

相關問題