传递System.Data.Linq.ModifiedMemberInfo列表时对象全为空的问题
你的问题核心在于Linq to SQL的GetModifiedMembers方法依赖DataContext对实体的状态跟踪,如果跟踪机制没有正确工作,就会返回空的ModifiedMemberInfo集合。下面是最常见的几个原因及对应的排查方向:
1. 实体未被当前DataContext跟踪
GetModifiedMembers只能识别由当前db实例加载或跟踪的实体。如果dbDoc是以下情况,DataContext根本不知道它的初始状态,自然无法检测变化:
- 手动
new出来的实体(不是通过db.tblVendorPackingSlipHeaders查询得到的) - 从另一个DataContext实例获取的实体(比如跨上下文传递的对象)
- 之前被调用
db.Detach(dbDoc)从跟踪中移除的实体
排查方式:检查dbDoc的来源,确保它是通过当前db实例查询获取的,比如:
// 正确:从当前DataContext加载实体 var dbDoc = db.tblVendorPackingSlipHeaders.FirstOrDefault(h => h.Id == yourHeaderId);
2. 实体实际上没有被修改
如果在调用GetModifiedMembers之前,你没有对dbDoc的任何属性做过更改,那么方法自然会返回空集合。这看起来是常识,但很容易被忽略——比如你以为修改了属性,但实际代码逻辑没走到修改步骤,或者修改的值和原始值完全一致。
排查方式:在调用GetModifiedMembers前,添加调试代码确认属性确实被修改:
Console.WriteLine($"Original Value: {dbDoc.SomeField}"); dbDoc.SomeField = "UpdatedValue"; Console.WriteLine($"Updated Value: {dbDoc.SomeField}"); // 再获取变化 var changes = db.tblVendorPackingSlipHeaders.GetModifiedMembers(dbDoc).ToList();
3. DataContext的跟踪功能被禁用
Linq to SQL的DataContext默认启用对象跟踪,但如果db的ObjectTrackingEnabled属性被设置为false,它就不会跟踪实体的变化,GetModifiedMembers也就无法返回任何数据。
排查方式:在调用方法前检查这个属性:
if (!db.ObjectTrackingEnabled) { // 跟踪被禁用,需要开启才能检测变化 db.ObjectTrackingEnabled = true; }
4. 已提前提交了更改
如果在调用GetModifiedMembers之前,你已经调用过db.SubmitChanges(),DataContext会重置所有跟踪的变化状态,此时再获取修改成员就会得到空集合。
正确流程:应该先获取修改记录,再提交更改:
// 1. 修改实体 dbDoc.SomeField = "NewValue"; // 2. 获取修改记录并审计 var changes = db.tblVendorPackingSlipHeaders.GetModifiedMembers(dbDoc).ToList(); recordHeaderChanges(changes, User.Identity.Name); // 3. 最后提交更改 db.SubmitChanges();
额外提示
你可以通过db.GetChangeSet()方法查看当前DataContext跟踪的所有变化,这有助于快速确认是否有修改被检测到:
var changeSet = db.GetChangeSet(); Console.WriteLine($"Modified entities: {changeSet.Updates.Count}");
内容的提问来源于stack exchange,提问作者boruchsiper

