我有一个类型obj
的Linq-To-SQL对象MyClass
,我已经通过我的数据上下文加载了它。
现在我想强制该对象保存,即使没有实际更改过的字段,这样保存操作可以在幕后设置一些触发器。
让我的数据上下文认为obj
很脏的最简单方法是什么,以便调用SubmitChanges()
会导致obj
被保存?
答案 0 :(得分:7)
只需将属性更改为虚拟值,然后返回...
var value = obj.SomeField;
obj.SomeField = "dummy";
obj.SomeField = value;
dc.SubmitChanges();
编辑:让我把它拿回来。 L2S更改跟踪器不会被这种愚弄。如果您不想更改任何现有列,最简单/最干净/最安全的方法可能是添加新列并更改它。
如果您绝对无法进行任何数据库更改(即添加新列),则可以选择使用反射进行更改跟踪器。我没有尝试过,但看起来这样的路线(粗略地):
1)datacontext有一个名为services的私有成员
2)服务指向CommonDataServices,它有一个私有成员跟踪器和一个内部成员ChangeTracker(返回前者)。
3)更改跟踪器有一个GetTrackedObject内部方法,它返回一个TrackedObject
4)TrackedObject有一个ConvertToModified方法......
编辑#2:我刚测试了上面的反射路线,似乎有效。 E.g:
using (advWorksDataContext dc = new advWorksDataContext())
{
Employees emp = dc.Employees.FirstOrDefault();
dc.MakeDirty(emp);
dc.SubmitChanges();
}
...... MakeDirty的实现是:
public static class DCExtensions
{
internal static void MakeDirty(this System.Data.Linq.DataContext dc, object someEntity)
{
//get dc type
Type dcType = dc.GetType();
while (dcType != typeof(System.Data.Linq.DataContext))
{
dcType = dcType.BaseType;
}
//get hold of the CommonDataServices thing in the DC
System.Reflection.FieldInfo commonDataServicesField
= dcType.GetField("services", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
object commonDataServices = commonDataServicesField.GetValue(dc);
Type commonDataServicesType = commonDataServices.GetType();
//get hold of the change tracker
System.Reflection.PropertyInfo changeTrackerProperty
= commonDataServicesType.GetProperty("ChangeTracker", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
object changeTracker = changeTrackerProperty.GetValue(commonDataServices, null);
Type changeTrackerType = changeTracker.GetType();
//get the tracked object method
System.Reflection.MethodInfo getTrackedObjectMethod
= changeTrackerType.GetMethod("GetTrackedObject", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
object trackedObject = getTrackedObjectMethod.Invoke(changeTracker, new object[] { someEntity } );
//get the ConvertToModified method
Type trackedObjectType = trackedObject.GetType();
System.Reflection.MethodInfo convertToModifiedMethod
= trackedObjectType.GetMethod("ConvertToModified", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
//call the convert to modified method
convertToModifiedMethod.Invoke(trackedObject, null);
}
}
答案 1 :(得分:0)
你可以尝试2次提交,如果这不会打破别的吗?因此,您可以使用Kristofer的第一个答案的变体:
Just change a property to a dummy value, save it, and then change back...
var value = obj.SomeField;
obj.SomeField = "dummy";
dc.SubmitChanges();
obj.SomeField = value;
dc.SubmitChanges();
对你的目的有什么好处吗?