我很难尝试调试LINQ to SQL并提交更改.
我一直在使用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:根据sirrocco的建议,我已经改为InsertOnSubmit,仍然会出现同样的错误.
编辑3: 我已经实现了Sam的建议,试图记录生成的SQL并捕获ChangeExceptoinException.这些建议没有任何消息,当我抛出异常时,我实际上从未实际生成SQL.
编辑4: 我找到了一个对我有用的答案.它只是一个理论,但它已经解决了我目前的问题.
我总是觉得有用的是确切地知道在SubmitChanges()方法中发送到DataContext的更改.
我使用DataContext.GetChangeSet()方法,它返回一个ChangeSet对象实例,该实例包含已添加,修改或删除的3个只读IList对象.
您可以在SubmitChanges方法调用之前放置一个断点,并添加一个Watch(或Quick Watch),其中包含:
ctx.GetChangeSet();
其中ctx是DataContext的当前实例,然后您将能够跟踪在SubmitChanges调用中有效的所有更改.
首先,感谢大家的帮助,我终于找到了它.
解决方案是从项目中删除.dbml文件,添加一个空白.dbml文件,并使用"服务器资源管理器"中的项目所需的表重新填充它.
我在做这件事时注意到了几件事:
系统中有几个表以两个单词命名,单词之间有一个空格,即"Job Master".当我将该表拉回到.dbml文件中时,它将创建一个名为"Job_Master"的表,它将用下划线替换该空格.
在原始.dbml文件中,我的一个开发人员已经浏览了.dbml文件并删除了所有下划线,因此'job_Master'将成为.dbml文件中的'JobMaster'.在代码中,我们可以在更多的标准命名约定中引用该表.
我的理论是在某个地方,从"JobMaster"到"Job Master"的转换虽然在进行投影时丢失了,但我仍然不断提出数组越界错误.
这只是一种理论.如果有人能够更好地解释它,我希望在这里有一个具体的答案.
我的第一个调试操作是查看生成的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); } } }