Какой самый чистый способ сделать объект Linq «грязным»? - PullRequest
2 голосов
/ 24 августа 2009

У меня есть объект Linq-To-SQL obj типа MyClass, который я загрузил через мой контекст данных.

Теперь я хочу принудительно сохранить этот объект, даже если в действительности поля не были изменены, чтобы действие сохранения могло вызвать некоторые триггеры за сценой.

Какой самый простой способ заставить мой контекст данных думать, что obj грязный, так что вызов SubmitChanges() приведет к сохранению obj?

Ответы [ 2 ]

7 голосов
/ 24 августа 2009

Просто измените свойство на фиктивное значение, а затем вернитесь ...

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);
    }
}
0 голосов
/ 24 августа 2009

Вы могли бы попробовать 2 представления, если это не сломает что-нибудь еще? Поэтому вы можете просто использовать вариант первого ответа Кристофера:

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();

Есть что-нибудь хорошее для ваших целей?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...