使用LINQ-to-SQL时,可以通过调用DataContext.GetChangeSet()
来获取一组将更新,插入或删除的对象数组。如果存在冲突,则DataContext.ChangeConflicts
属性将为您提供对原始对象和已更改对象的引用。如果没有冲突,是否有办法访问原始和已更改的对象?在LINQ-to-SQL变更集中获取对象的原始副本
这需要对不执行INotifyPropertyChanging
/INotifyPropertyChanged
实体合作。
使用LINQ-to-SQL时,可以通过调用DataContext.GetChangeSet()
来获取一组将更新,插入或删除的对象数组。如果存在冲突,则DataContext.ChangeConflicts
属性将为您提供对原始对象和已更改对象的引用。如果没有冲突,是否有办法访问原始和已更改的对象?在LINQ-to-SQL变更集中获取对象的原始副本
这需要对不执行INotifyPropertyChanging
/INotifyPropertyChanged
实体合作。
我没能找到一种方法,通过公共API来做到这一点。但是,如果你愿意反思一下(最好是some compiled expressions to invoke any methods, constructors, and get accessors),就有可能获得数据。
这里就是你需要做的:
DataContext
实例的私有services
领域。System.Data.Linq.ChangeProcessor
一个实例。这是您拨打DataContext.GetChangeset()
时实际使用的内部类。通过在从步骤1中的参考services
,以及到DataContext
实例的引用。ChangeProcessor
实例调用私有和无参数GetOrderedList
方法。这会给你一个List<TrackedObject>
。不幸的是,因为TrackedObject
也是一个内部类,所以您还需要使用反射来访问它的属性。TrackedObject
实例的Current
和Original
性能。它还有其他一些有用的属性,例如IsNew
,IsModified
和IsDeleted
,这些都是不言自明的,以及IsInteresting
,我假设这三个属性都是真实的。当然,因为这些都是内部API,所以在框架更新时它们可能会发生变化,所以在使用此逻辑时请记住这一点。
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);
});