使Linq对象“肮脏"的最干净方法是什么? [英] What's the cleanest way to make a Linq object "dirty"?
问题描述
我有一个类型为MyClass
的Linq-To-SQL对象obj
,该对象是通过数据上下文加载的.
I have a Linq-To-SQL object obj
of type MyClass
that I have loaded via my data context.
现在,即使没有实际更改的字段,我也想强制保存该对象,以便保存操作可以在后台触发一些触发器.
Now I want to force that object to save, even if no fields have actually changed, so that the save action can set off some triggers behind the scenes.
最简单的方法是使我的数据上下文认为obj
是脏的,以便对SubmitChanges()
的调用将导致保存obj
?
What's the easiest way of making my data context think that obj
is dirty, so that a call to SubmitChanges()
will cause obj
to be saved?
推荐答案
只需将属性更改为虚拟值,然后返回...
Just change a property to a dummy value and then back...
var value = obj.SomeField;
obj.SomeField = "dummy";
obj.SomeField = value;
dc.SubmitChanges();
编辑:让我回顾一下. L2S更改跟踪器不会因此而被愚弄.如果您不想更改任何现有列,最简单/最干净/最安全的方法可能是添加新列并进行更改.
let me take that back. The L2S change tracker won't be fooled by that. The easiest/cleanest/safest way if you don't want to change any of the existing columns is probably to add a new column and change that.
如果您绝对不能进行任何数据库更改(即添加新列),则可以选择使用反射来进行更改跟踪.我还没有尝试过,但是看起来(大概)的路线是:
If you absolutely can't make any db changes (i.e. add a new column), then going at the change tracker with reflection might be an option. I haven't tried it, but it looks like the route to that would be (roughly):
1)数据上下文具有一个称为服务的私有成员.
2)服务指向CommonDataServices,它具有一个私有成员跟踪器和一个内部成员ChangeTracker(返回前者).
3)变更跟踪器具有GetTrackedObject内部方法,该方法返回TrackedObject.
4)TrackedObject有一个ConvertToModified方法...
1) the datacontext has a private member called services.
2) services points to a CommonDataServices which has a private member tracker and an internal member ChangeTracker (returning the former).
3) Change trackers has a GetTrackedObject internal method that returns a TrackedObject.
4) TrackedObject has a ConvertToModified method...
编辑#2:我刚刚测试了上面的反射路径,它似乎可以工作.例如:
Edit #2: I just tested the reflection route above and it seems to work. E.g.:
using (advWorksDataContext dc = new advWorksDataContext())
{
Employees emp = dc.Employees.FirstOrDefault();
dc.MakeDirty(emp);
dc.SubmitChanges();
}
...并且MakeDirty的实现是:
...and the implementation of MakeDirty is:
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);
}
}
这篇关于使Linq对象“肮脏"的最干净方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!