2016-01-12 37 views
2

沒有進入「爲什麼」,才明白這一點繼承和我有什麼用:)實體框架的地圖數據錯誤時,標識列不是唯一的

工作,我有一個EF6 EDMX映射到一個視圖。沒有標識列,因此爲了EF映射實體,第一個非空列被選爲PK。這背後的原始想法是只讀不會更新或刪除。沒有過濾(ODATA位於此之上),而且只有 - 我的意思是 - 實體使用的方式是select top N *

視圖中有4條記錄。

TypeCode | Contact | UserID | LocaleID | EntityName 
--------------------------------------------------------- 
1   6623  1032  9   Jane 
1   6623  1032  9   Jane 
1   6623  1032  9   John 
1   6623  1032  9   John 

我看到的問題是,EF映射所有4行相同。上面所有的「約翰」名字變成了「簡」

好的,擱置設計決定,事實上在視圖上沒有識別記錄,爲什麼EF映射最後兩行是錯誤的?我最初的想法是,因爲「PK」被設置爲TypeCode它不知道該怎麼做。但是,當從數據庫讀取結果時,爲什麼會使用鍵列?我原以爲它只適用於更新和刪除

+0

喬,這是否有關係,爲什麼,這是衆所周知的工作方式,你必須忍受。 –

+0

@IvanStoev它是否已知?它實際上是否使用定義爲密鑰選擇的列? – Joe

+0

好吧,看起來像。沒有文檔或解釋鏈接,我從這個線程學到了[在LINQ和SQL中看似等價的查詢返回不同的結果](http://stackoverflow.com/questions/33583309/seemingly-equivalent-queries-in-linq -and-sql-returns-different-results),但在其他許多地方發現類似。 –

回答

3

如果您通過實體框架查詢數據,默認行爲是每個物化實體通過其唯一鍵進行跟蹤。唯一的密鑰由您告知EF用作密鑰的任何屬性組成,或者,也可以推斷爲關鍵屬性(您的案例中爲TypeCode)。只要重複的實體鍵試圖進入變更追蹤器,就會拋出一個錯誤,告訴對象已被追蹤。

因此EF只是不能實現具有重複主鍵值的對象。它會損害其跟蹤機制。

看來,至少在EF6中,AsNoTracking()可以用作解決方法。 AsNoTracking告訴EF只是物化對象而不跟蹤它們,所以它不會生成實體鍵。

什麼我明白是爲什麼EF不讀取重複的主鍵值時不會引發異常。現在它默默地返回同一個對象,因爲它在SQL查詢結果中遇到它的鍵值。這導致許多人不知所措。

順便說一句,避免此問題的常用方法是通過在Sql Server中使用ROW_NUMBER生成視圖的臨時唯一鍵值。這對於只讀數據到一個上下文實例中的只讀數據來說已經足夠了。

+0

我上面的問題是一個非常簡化的版本。瘋狂的事情是,這是4行。表中有14K條記錄,全都具有相同的TypeCode值,並且不具有相同的行爲。我能想到的唯一的事情就是那4條記錄共享其他3列的數據。我認爲在實現記錄時,EF可能不僅僅是一個「簡單」的身份映射模式。無論哪種方式,我都會嘗試使用'AsNoTracking'並查看結果。 – Joe

+0

只是好奇,你知道EF代碼在哪裏完成嗎?我在他們的Github周圍狩獵,但無濟於事 – Joe

+0

我經常挖掘EF代碼,但如果我知道這一點,我會成爲一名專家。但是,通過了解這一點你會獲得什麼?實際上不可能修改這種行爲(如果你願意的話),因爲它是EF追蹤機制的根源。 –

相關問題