c# - 制作 Linq 对象 "dirty"的最干净的方法是什么?

标签 c# linq linq-to-sql

我有一个类型为 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/

相关文章:

LINQ-to-SQL:为什么我不能使用表名作为参数?

c# - 任务列表中出现奇怪的空条目

优化一次查询中的LinQ最大日期

c# - 如何在 LINQ 中分组?

c# - linq查询返回唯一项的嵌套列表

c# - 第一次引发 Elapsed 事件时进行测试。有效还是无用?

c# - Matlab Coder - 从 .m 文件生成 EXE

c# - Xamarin.Forms FontAwesome 不适用于绑定(bind)属性

c# - LINQ to SQL 业务对象创建最佳实践

c# - 如何在 C# 中使用具有相同表的两个数据库?