引言
網上介紹Linq TO SQL的資料不少,但是實際工程中的例子很少,本文是我在使用Linq TO SQL開發項目中遇到的異常及解決方法,希望對您有幫助.
本文會繼續更新...
系統環境
Visual Studio 2008 NET Framework 3.5+Microsoft SQL Server 2005+Window XP+ SP3
LINQ TO SQL采用配置式開發
常見異常
本文基本上使用斷開的DataContext方式下開發中出現的異常。
[System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException]: {"對象的當前狀態使該操作無效。"}
在使用斷開方式的DataContext時候,如果當前對象沒有序列化,會產生此異常。
解決辦法:生成Map文件時候序列化參數選擇'Unidirectional' 如下:
sqlMetal /conn:server=.;database=ERP;uid=sa;pwd=Mypass800624 /code:D:\ERP.cs /Map:D:\ERP.map /namespace:DMN /serialization:Unidirectional
產生原因:斷開模式下,對象要進行Attach對象上下文中才能進行Save操作,就是說要以流的形式進行數據表達,因此如果對象沒有序列化,就是出現此異常
[System.Runtime.Serialization.SerializationException]: {"類型的對象圖包含循環,如果禁用引用跟蹤,擇無法對其進行序列化。"}
在使用斷開方式的DataContext時候,在遞歸保存對象的時候,如果子對象沒有序列化,會發生此異常
解決辦法:同上
產生原因:斷開模式下,對象進行遞歸Save操作時候,子對象要先Detach下來然後Attach上去,,就是說要以流的形式進行數據表達,因此如果子對象沒有序列化,就是出現此異常
[System.InvalidOperationException]: {"如果實體聲明了版本成員或者沒有更新檢查策略,則只能將它附加為沒有原始狀態的已修改實體。"}
在使用斷開方式的DataContext時候,在進行對象Save的的時候,如果該對象有Key,而Map文件中沒有版本策略聲明會有此異常
解決辦法:實際上這是個管理並發沖突的機制,可參考:微軟的官方文檔 我的解決辦法在Map文件中Key加上IsVersion屬性,因為我的主鍵為數據庫的自動標示,如下:
<column name="ID" member="ID" storage="_ID" dbtype="Int NOT NULL IDENTITY" isprimarykey="true" isdbgenerated="true" autosync="OnInsert" isversion="true" />
產生原因:斷開模式下,對象進行遞歸Save操作時候,如果該對象有Key,系統又找不到記這個對象被Modified過的策略,產生此異常。
未將對象引用設置到對象的實例。
使用方式我舉個例子:
string prece = " InDate >= DateTime.Parse(\"2008-08-09\")"; IList<Student> pp = LQDB.Where(prece); var source = from s in pp select new { s.ID, s.Name, s.IDO, s.InDate, s.FromSchool, NO = s.AMClass == null ? "" : s.AMClass.NO, ChargePMName = s.AMClass == null ? "" : s.AMClass.ChargePMName, RoomName =s.AMClass == null ?"": s.AMClass.RoomName, s.MB };
其中pp是我選擇的學生集合, 我重新組合,通過 NO = s.Class.NO得到學生班級編號,結果有的學生還沒有分班(我們外包培訓基地,業務比較特殊)導致班級 s.Class為Null
解決辦法:Null檢查,我的解決辦法,如下:
' var source = from s in pp select new { s.ID, s.Name, s.IDO, s.InDate, s.FromSchool, NO = s.AMClass == null ? "" : s.AMClass.NO};
產生原因:學生的類的Class為null,當然對Class的No引用就是產生此異常。