我有一个类型为 MyClass
的 Linq-To-SQL 对象 obj
,我已经通过我的数据上下文加载了它。
现在我想强制保存该对象,即使实际上没有更改任何字段,以便保存操作可以在幕后触发一些触发器。
让我的数据上下文认为 obj
是脏的最简单的方法是什么,以便调用 SubmitChanges()
将导致 obj
被拯救?
最佳答案
只需将属性更改为虚拟值,然后再返回...
var value = obj.SomeField;
obj.SomeField = "dummy";
obj.SomeField = value;
dc.SubmitChanges();
编辑:让我收回这句话。 L2S 更改跟踪器不会被它愚弄。如果您不想更改任何现有列,最简单/最干净/最安全的方法可能是添加一个新列并进行更改。
如果您绝对不能进行任何数据库更改(即添加新列),那么使用反射进入更改跟踪器可能是一种选择。我还没有尝试过,但看起来(大致)的路线是:
1) datacontext 有一个名为 services 的私有(private)成员。
2) services指向一个CommonDataServices,它有一个私有(private)成员tracker和一个内部成员ChangeTracker(返回前者)。
3) Change trackers 有一个 GetTrackedObject 内部方法,返回一个 TrackedObject。
4) TrackedObject 有一个 ConvertToModified 方法...
编辑 #2: 我刚刚测试了上面的反射路由,它似乎有效。例如:
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);
}
}
关于c# - 制作 Linq 对象 "dirty"的最干净的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1321255/