2010-08-01 119 views
10

我越來越實體框架和繼承:NotSupportedException異常

System.NotSupportedException:在EntitySet的 'Entities.Message' 所有 對象必須具有唯一 主鍵。然而, 類型的實例「Model.Message」和實例類型「Model.Comment」兩個 有 相同的主鍵值

,但我不知道這意味着什麼。

使用EF4,我有一堆消息類型的實體。其中一些消息實際上是一種子類型,Comment,按表類型繼承。只是

DB.Message.First(); 

會產生異常。我有其他的子類型實例,我沒有遇到問題,但我看不到任何差異。但是,有時候,如果我重新啓動開發服務器,問題就會消失,但並非總是如此。

編輯: 我已經制定了(應該有),該問題是存儲過程提取我的消息的錯誤。由於所有與Message有關的字段都被提取,所以當前設置的方式是由存儲過程忽略Comment表。然後,上下文繼續討論這個問題,可能通過再次提取那些也是評論的消息,正如你所建議的那樣。如何正確地做到這一點是當前的核心問題。我在http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/bb0bb421-ba8e-4b35-b7a7-950901adb602找到了解決方案的一些跡象。

+0

你可以發佈消息和評論類的簽名嗎? – Basic 2010-09-05 23:40:34

+0

對不起,我不瞭解你。你想看看成員嗎?所有這些或只是EF生成的? – Martin 2010-09-06 13:42:32

+0

你有沒有檢查過這個bug? https://connect.microsoft.com/VisualStudio/feedback/details/544639/ef4-inheritance-defined-using-queryview-doesnt-work-properly-with-association – 2010-09-07 01:33:18

回答

0

我不是一個EF類型的人(忙於與NHibernate合作,還沒有時間與EF進行更新),所以我可能在這裏完全錯誤,但問題可能是兩個表(因爲你正在使用每種類型的繼承)有主鍵衝突?

如果您檢查兩個表中的數據,主鍵值是否會發生碰撞?

+0

嗯,是的,他們應該。如果你不相信我,相信EF。有一個叫做「從模型構建數據庫」的漂亮的小命令... – Martin 2010-09-07 11:15:26

1

聽起來好像你正在將兩條記錄放入內存中,一條寫入消息,一條寫入註釋。

可能prblems:

  • 有具有相同ID
  • 同樣的消息被拉起的消息和
  • 同樣的消息被拉起評論兩次到兩個物理信息相同的上下文

問題有時會在您重新啓動時消失,指出清理上下文時出現問題。你在使用「使用」語句嗎?

您是否有從消息更改爲評論的功能?

+0

不,沒有這樣的功能。請參閱編輯。 – Martin 2010-09-14 10:09:20

2

正如你推斷的,它看起來像上下文獲取評論作爲消息(不知道它是一個評論)。之後,您會詢問實際的評論,以便上下文獲取評論。現在在Context中有兩個對象實例具有相同的ID - 一個是消息,一個是註釋。

似乎在兩個對象都被加載之後(即,當您嘗試第二次訪問消息時),異常不會被拋出。如果您可以在加載註釋時找到從上下文中刪除消息的方法,則可以解決您的問題。

另一種選擇可能是使用Table-per-hierarchy模型。這會導致錯誤的數據庫設計,但在一天結束時,您必須使用有效的數據庫設計。

您可以通過確保首先將對象作爲註釋加載來避免此問題。這樣,當你要求消息時,Context已經知道它。

也可以考慮使用Composition over Inheritance,這樣一個消息有0..1個CommentDetails。

最後的建議是從控制代碼中刪除對實體框架的依賴關係,並創建引用EF並檢索對象的數據訪問層。 DAL可以將實體框架對象轉換爲一組不同的實體對象,這些對象更易於在代碼中使用。這種方法會產生大量的代碼開銷,但如果您不能使用實體框架來生成一個實體模型,並以您想使用它們的方式來表示實體,那麼這種方法可能會適用。總而言之,除非MS解決了這個問題,否則你的問題沒有解決方案,而不需要重新考慮你的方法。不幸的是,實體框架並不理想,特別是對於複雜的實體模型 - 您最好創建自己的DAL並完全繞過EF。