異常跟蹤之CLR 型別到 EDM 型別的對映不明確

2021-09-08 18:52:20 字數 2138 閱讀 4959

異常資訊:

"

指定的架構無效。錯誤:

clr 型別到 edm 型別的對映不明確,因為多個 clr 型別與 edm 型別「person」匹配。

以前找到的是 clr 型別「a.person」,

新找到的則是 clr 型別「b.person」。

這類異常資訊在**裡面出現過幾次,每次的解決方案都讓人匪夷所思。不知道為什麼出現,也不知道為什麼被解決了。

但實際情況是,這類異常不總是出現,而是在乙個偶然的情況下出現。所謂偶然的情況,卻是一種很普通又簡單的呼叫。

using (var con = new

mycontainer())

查詢cat資料,將第乙個的name資料查詢並儲存在contract.dog物件中。這類呼叫非常普通。

1. 出現"

clr 型別到 edm 型別的對映不明確"異常,肯定是存在和ef模型中資料結構一樣的類。

2. 與ef資料結構同名的類一直存在,但並非一直報錯。

做以下測試:

在ef資料模型所在專案中(以下用entity表示),建立模型person

同時,在entity專案中另外新建乙個類,也命名為person(當然命名空間不一樣),屬性一樣(型別和名稱)。

除錯時,會發現報錯,報錯內容同上。

在測試一的基礎上,去掉entity中手動建立的person類,在解決方案下新建另乙個專案contract,在contract中新建類,命名person,屬性同上。

呼叫**:

using (var con = new

mycontainer())

單獨執行這段時,不會報錯。加上下面這段:

using (var con = new

mycontainer())

執行完上面**後,緊接著執行下面的**。出現異常,異常同上。

加斷點,跟蹤con的資料明細。

在執行完第一段查詢以前,con.base._internalcontext.objectcontext.metadataworkspace._itemocspace.value(以下簡稱metaocspace)為空;

執行完第一段查詢後,metaocspace的數量出現32條,具體如下:

出現了person的型別對映資料,此時person型別對映到了contract.person。

省略其他測試過程,有如下結論:

1. 當entity**現同資料模型的類時,同類名同字段,無論什麼時候用ef運算元據,都會報錯。

2. 當entity所在的assembly沒有同名類,但其他assembly(例contract)有同名類時。先有查詢結果放入entity的任意類物件,後有查詢結果放入contract的任意類物件時,就會報錯。操作的先後順序調換,結果一樣。

這是因為dbcontext的metadataworkspace一旦生成會快取起來。也就是說,在同乙個應用程式域裡面,一旦用dbcontext操作過資料庫,它會自動讀取類所在assembly裡面的所有類,並嘗試匹配資料庫模型,然後將匹配結果儲存起來(儲存到上面的metaocspace中)。當下次運算元據庫時,返回資料對應類類所在其它assembly裡面的類與當前已匹配資料庫模型發生衝突時,便會報錯。

3. 當client引用entity + client引用contract時,有結論2的隱患。而當entity引用contract,然後client引用entity時,同樣存在問題。

這種情況一般出現在ef的列舉型別定義為引用外部型別(contract中定義的型別),這時就會出現entity引用contract,然後client引用entity的場景。配合以下**:

using (var con = new

mycontainer())

這時,也會出現報錯。

解決思路:

1. 不要與entity中的模型同名,同欄位。或者換過來entity中的模型加特殊標記

2. ef運算元據庫時,返回資料的資料型別必須用entity專案中定義的型別。

異常的型別

throwable error error是由於系統錯誤 是無法恢復的 exception 編譯時異常 可查異常 必須處理,不處理編譯是通不過的,兩種處理方式 要麼throw出去要麼catch處理掉 runtimeexception unchecked exception 執行時才出的異常,編譯是檢...

常見的異常型別

1.異常結構層次的根類 exception 2.算術錯誤形式,如以零作除數 arithmeticexception 3.陣列下標越界 arrayindexoutofbound ception 4.嘗試訪問null物件成員 nullpointerexception 5.不能載入所需的類 classno...

十一 認識基元型別 FCL型別及與CLR的相容情況

基元型別 primitive 簡單來說就是編譯器直接支援的資料型別。基元型別直接對映到framework類庫 fcl 中的型別,例如c 中乙個基元型別int直接對映到system.int32型別,如下 public sealed class program public sealed class p...