3

使用 LINQ-to-SQL 时,可以通过调用DataContext.GetChangeSet(). 如果存在冲突,该DataContext.ChangeConflicts属性将为您提供对原始对象和更改对象的引用。如果没有冲突,有没有办法访问原始和更改的对象?

这需要适用于不实现INotifyPropertyChanging/的实体INotifyPropertyChanged

4

2 回答 2

3
var db = new DataContext();
db.GetChangeSet().Updates.ForEach(o => {
    var currentObject = o;
    var originalObject = db.GetTable(o.GetType()).GetOriginalEntityState(o);
    var changedProperties = db.GetTable(o.GetType()).GetModifiedMembers(o);
});
于 2012-07-25T03:30:35.287 回答
0

我无法找到通过公共 API 执行此操作的方法。但是,如果您愿意稍微使用反射(最好是一些编译的表达式来调用任何方法、构造函数和 get 访问器),则可以获取数据。

这是您需要做的:

  1. 获取对您实例的私有services字段的引用。DataContext
  2. 创建一个System.Data.Linq.ChangeProcessor. 这是一个内部类,当您调用DataContext.GetChangeset(). 传入services来自步骤 1 的引用以及对DataContext实例的引用。
  3. GetOrderedList针对您的ChangeProcessor实例调用私有且无参数的方法。这会给你一个List<TrackedObject>. 不幸的是,由于TrackedObject它也是一个内部类,因此您还需要使用反射来访问其属性。
  4. 我们正在寻找的对象在实例的CurrentOriginal属性中。TrackedObject它还有一些其他有用的属性,例如IsNewIsModifiedIsDeleted,它们都是不言自明的,还有IsInteresting,我假设它们代表了前三个属性中的任何一个为真。

当然,由于这些都是内部 API,因此在框架更新时它们可能会发生变化,因此在使用此逻辑时请记住这一点。

于 2012-04-11T18:42:45.373 回答