2008-09-17 69 views
21

我很難嘗試調試LINQ to SQL並提交更改。調試LINQ to SQL SubmitChanges()

我一直在使用http://weblogs.asp.net/scottgu/archive/2007/07/31/linq-to-sql-debug-visualizer.aspx,這對調試簡單查詢非常有用。

我在DataContext類的工作我從我的應用程序下面的代碼片段項目:

JobMaster newJobToCreate = new JobMaster(); 
newJobToCreate.JobID = 9999 
newJobToCreate.ProjectID = "New Project"; 
this.UpdateJobMaster(newJobToCreate); 
this.SubmitChanges(); 

我會捕捉一些很奇怪的例外,當我運行this.SubmitChanges;

Index was outside the bounds of the array. 

堆棧跟蹤去的地方,我不能踏進:

at System.Data.Linq.IdentityManager.StandardIdentityManager.MultiKeyManager`3.TryCreateKeyFromValues(Object[] values, MultiKey`2& k) 
    at System.Data.Linq.IdentityManager.StandardIdentityManager.IdentityCache`2.Find(Object[] keyValues) 
    at System.Data.Linq.IdentityManager.StandardIdentityManager.Find(MetaType type, Object[] keyValues) 
    at System.Data.Linq.CommonDataServices.GetCachedObject(MetaType type, Object[] keyValues) 
    at System.Data.Linq.ChangeProcessor.GetOtherItem(MetaAssociation assoc, Object instance) 
    at System.Data.Linq.ChangeProcessor.BuildEdgeMaps() 
    at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode) 
    at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode) 
    at System.Data.Linq.DataContext.SubmitChanges() 
    at JobTrakDataContext.CreateNewJob(NewJob job, String userName) in D:\JobTrakDataContext.cs:line 1119 

沒有人有任何工具或他們使用的技術?我錯過了一些簡單的東西嗎

編輯: 我使用Slace的建議已經安裝.NET調試,但是.NET 3.5的代碼尚未提供:http://referencesource.microsoft.com/netframework.aspx

EDIT2: 我改成InsertOnSubmit按希洛可風式的建議,仍然得到相同的錯誤。

EDIT3: 我已經實現了Sam的建議,嘗試記錄生成的SQL並捕獲ChangeExceptoinException。這些建議沒有多少亮點,當我拋出異常時,我實際上從未真正開始生成SQL。

EDIT4: 我在下面找到了適合我的答案。它只是一個理論,但它已經解決了我目前的問題。

+0

許多客戶端發生此錯誤,只有在裝有Windows XP的機器上,我發現這個熱修復可以解決問題。 [I386](http://hotfixv4.microsoft.com/.NET%20Framework%203.5%20-%20Windows%20Server%202003,%20WindowsXP,%20Windows%20Vista,%20Windows%20Server%202008%20(MSI)/ sp1/DevDiv975687/30729.5821/free/448814_intl_i386_zip.exe)和[x64](http://support.microsoft.com/hotfix/KBHotfix.aspx?kbnum=963657&kbln=en-us) – gpiccin 2013-05-25 21:12:40

回答

8

首先,感謝大家的幫助,我終於找到了它。

解決的辦法是從項目中刪除.dbml文件,添加一個空白的.dbml文件,並使用「服務器資源管理器」中我的項目所需的表重新填充它。

我注意到有幾件事情我是這樣做的同時:

  • 有系統幾張桌子用兩個字命名,並在單詞之間的空間,即「在職研究生」。當我將表拉回到.dbml文件時,它會創建一個名爲'Job_Master'的表,它將用下劃線替換空格。
  • 在原始的.dbml文件中,我的一位開發人員瀏覽了.dbml文件並刪除了所有下劃線,因此'Job_Master'將成爲.dbml文件中的'JobMaster'。在代碼中,我們可以更多地參考表格,對於我們來說,標準的命名約定。
  • 我的理論是,在某個地方,從'JobMaster'到'Job Master'的翻譯雖然在進行投影時丟失了,但我一直想出數組越界的錯誤。

這只是一個理論。如果有人能更好地解釋它,我想在這裏有一個具體的答案。

1

一個簡單的解決方案可能是在您的數據庫上運行一個跟蹤並檢查針對它運行的查詢 - 過濾掉的課程來整理其他應用程序等訪問數據庫。

當然,只有當你通過例外......

0

Hrm。

考慮一個WAG(Wild Ass Guess),它在我看來像LINQ - SQL試圖找到一個不存在的id對象,基於創建JobMaster類的方式。是否有與該表相關的外鍵,使得LINQ to SQL試圖獲取可能不存在的類的實例?你似乎將新對象的ProjectID設置爲一個字符串 - 你真的有一個ID是一個字符串?如果您嘗試將其設置爲新項目,則需要創建一個新項目並獲取其ID。

最後,UpdateJobMaster做什麼?它是否可以做一些上述的事情?

2

你上面提到的錯誤由則通常會導致協會指向錯誤的方向。當手動添加關聯到設計器時,這很容易發生,因爲與數據建模工具相比,L2S設計器中的關聯箭頭指向後方。

如果他們拋出一個更具描述性的異常,他們會很高興,也許他們會在未來的版本。 (Damien/Matt ...?)

1

爲什麼在新實例上執行UpdateJobMaster?不應該是InsertOnSubmit?

JobMaster newJobToCreate = new JobMaster(); 
newJobToCreate.JobID = 9999 
newJobToCreate.ProjectID = "New Project"; 
this.InsertOnSubmit(newJobToCreate); 
this.SubmitChanges(); 
+0

我已更改爲InsertOnSubmit,仍然收到相同的錯誤 – ben 2008-09-18 14:55:50

4

您可以創建一個部分類爲您的DataContext並使用創建的或者你自己設置的部分方法的日誌,包裹在一個#如果DEBUG的console.out ..這將有助於你看在調試您正在使用的datacontext的任何實例時執行的查詢。

我發現這個有用的,而調試的LINQ to SQL的異常..

partial void OnCreated() 
{ 
#if DEBUG 
     this.Log = Console.Out; 
#endif 
} 
6

我的第一個調試行動將看看生成的SQL:

JobMaster newJobToCreate = new JobMaster(); 
newJobToCreate.JobID = 9999 
newJobToCreate.ProjectID = "New Project"; 
this.UpdateJobMaster(newJobToCreate); 
this.Log = Console.Out; // prints the SQL to the debug console 
this.SubmitChanges(); 

第二是捕捉ChangeConflictException並查看失敗的細節。

catch (ChangeConflictException e) 
    { 
    Console.WriteLine("Optimistic concurrency error."); 
    Console.WriteLine(e.Message); 
    Console.ReadLine(); 
    foreach (ObjectChangeConflict occ in db.ChangeConflicts) 
    { 
     MetaTable metatable = db.Mapping.GetTable(occ.Object.GetType()); 
     Customer entityInConflict = (Customer)occ.Object; 
     Console.WriteLine("Table name: {0}", metatable.TableName); 
     Console.Write("Customer ID: "); 
     Console.WriteLine(entityInConflict.CustomerID); 
     foreach (MemberChangeConflict mcc in occ.MemberConflicts) 
     { 
     object currVal = mcc.CurrentValue; 
     object origVal = mcc.OriginalValue; 
     object databaseVal = mcc.DatabaseValue; 
     MemberInfo mi = mcc.Member; 
     Console.WriteLine("Member: {0}", mi.Name); 
     Console.WriteLine("current value: {0}", currVal); 
     Console.WriteLine("original value: {0}", origVal); 
     Console.WriteLine("database value: {0}", databaseVal); 
     } 
    } 
    } 
+0

我的應用永遠不會生成SQL,也不會生成任何ChangeConflictException,它在此步驟之前會被轟出。 – ben 2008-09-19 14:10:39

+3

不錯的一個。對於使用ASP.Net的人,只需更換控制檯即可。通過調試。在輸出窗口中獲取輸出 – citronas 2012-01-05 14:16:43

0

我們實際上已經停止使用Linq to SQL設計器來處理大型項目,而這個問題是其中一個主要原因。我們還改變了很多名稱,數據類型和關係的默認值,並且每隔一段時間,設計師就會失去這些更改。我從來沒有找到確切的原因,我也無法可靠地重現它。

這和其他限制一起導致我們放棄設計師並手工設計類。在習慣了模式之後,它實際上比使用設計器更簡單。

0

我今天早些時候在這裏發佈了一個類似的問題:Strange LINQ Exception (Index out of bounds)

這是一個不同的使用案例 - 在SubmitChanges()期間發生此錯誤的地方,我的過程發生在簡單查詢期間,但它也是索引超出範圍錯誤。

在萬一這個問題十字發佈數據的問題結合在一起,一個好撒瑪利亞人的答案要麼:)

0

檢查所有「主鍵」在你的dbml列實際上涉及到對主鍵數據庫表。我剛剛遇到了一種情況,設計師決定在dbml中添加一個額外的PK列,這意味着LINQ to SQL在保存時無法找到外鍵的兩側。

0

我最近遇到了同樣的問題:我所做的就是

Proce proces = unit.Proces.Single(u => u.ProcesTypeId == (from pt in context.ProcesTypes 
                     where pt.Name == "Fix-O" 
                     select pt).Single().ProcesTypeId && 
                     u.UnitId == UnitId); 

相反的:

Proce proces = context.Proces.Single(u => u.ProcesTypeId == (from pt in context.ProcesTypes 
                    where pt.Name == "Fix-O" 
                    select pt).Single().ProcesTypeId && 
                    u.UnitId == UnitId); 

如果背景是明顯的DataContext對象和「單元」單元對象的實例,一個來自dbml文件的數據類。

接下來,我使用「proce」對象在另一個Data Class對象的實例中設置一個屬性。可能LINQ引擎無法檢查我從「proce」對象設置的屬性是否在INSERT命令中被允許,LINQ將創建該屬性以將其他Data Class對象添加到數據庫。

30

我總是發現在SubmitChanges()方法中確切知道發送到DataContext的更改是否有用。

我使用DataContext.GetChangeSet()方法,它返回一個ChangeSet對象實例,它保存3個只讀的IList對象,這些對象已被添加,修改或刪除。

你可以把一個斷點剛剛的SubmitChanges方法調用之前,並添加手錶(或快速監視)包含:

ctx.GetChangeSet(); 

CTX哪裏是你的DataContext的當前實例,然後你會能夠跟蹤將在SubmitChanges調用中生效的所有更改。

0

我有同樣的非講話錯誤。

我有一個外鍵關係到一個不是表的主鍵,而是一個唯一的列的列。 當我將唯一列更改爲表的主鍵時,問題就消失了。

希望這有助於任何人!

0

發佈我的經驗與此異常的回答SO#237415

1

這幾乎肯定不會是所有人的根本原​​因,但我遇到了我的項目,這完全一樣的例外 - 發現,根本原因是在構建實體類期間正在拋出異常。奇怪的是,真正的異常是「丟失」,而是表現爲一個ArgumentOutOfRange異常,源於檢索對象的Linq語句的迭代器。

如果您收到此錯誤,並且您在POCO上引入了OnCreated或OnLoaded方法,請嘗試單步執行這些方法。

2

這是我做過什麼

... 
var builder = new StringBuilder(); 
try 
{ 
    context.Log = new StringWriter(builder); 
    context.MY_TABLE.InsertAllOnSubmit(someData); 
    context.SubmitChanges();     
} 
finally 
{ 
    Log.InfoFormat("Some meaningful message here... ={0}", builder); 
} 
0

我試圖調試我的LINQ ChangeConflictException當結束了在這個問題上。最後,我意識到這個問題是我手動在我的DBML文件中添加了一個屬性表,但我忘了設定的屬性,如可空(在我的情況應該是真實的)和服務器數據類型

希望這可以幫助某人。