Как получить дельта изменения сущности в EF? - PullRequest
8 голосов
/ 14 декабря 2011

Мне нужно получить список только измененных полей, хранилище данных ssce, поэтому триггеры недоступны

Есть ли какая-либо поддержка в EF для получения списка или создания универсального компонента?

Ответы [ 2 ]

7 голосов
/ 14 декабря 2011

В зависимости от типа контекста и сгенерированных объектов вы можете сделать это несколькими различными способами.В случае объектов, унаследованных от Entity или POCO, вы можете использовать ObjectStateManager, а в случае объектов с самопроверкой вы можете использовать Tracker от самого объекта.

, пожалуйста, предоставьте более подробную информацию о том,вы создали контекст и как вы вносите изменения

EDITED (2): вы можете запросить ObjectStateManager об измененных записях просто так:

 var changed = ctx.ObjectStateManager.GetObjectStateEntries().Where(e=>e.State != EntityState.Unchanged);

EDITED (1):

В следующем примере из MSDN показано, как запросить изменения:

int orderId = 43680;

using (AdventureWorksEntities context =
new AdventureWorksEntities())
{
var order = (from o in context.SalesOrderHeaders
             where o.SalesOrderID == orderId
             select o).First();

// Get ObjectStateEntry from EntityKey.
ObjectStateEntry stateEntry =
    context.ObjectStateManager
    .GetObjectStateEntry(((IEntityWithKey)order).EntityKey);

//Get the current value of SalesOrderHeader.PurchaseOrderNumber.
CurrentValueRecord rec1 = stateEntry.CurrentValues;
string oldPurchaseOrderNumber =
    (string)rec1.GetValue(rec1.GetOrdinal("PurchaseOrderNumber"));

//Change the value.
order.PurchaseOrderNumber = "12345";
string newPurchaseOrderNumber =
    (string)rec1.GetValue(rec1.GetOrdinal("PurchaseOrderNumber"));

// Get the modified properties.
IEnumerable<string> modifiedFields = stateEntry.GetModifiedProperties();
foreach (string s in modifiedFields)
    Console.WriteLine("Modified field name: {0}\n Old Value: {1}\n New Value: {2}",
        s, oldPurchaseOrderNumber, newPurchaseOrderNumber);

// Get the Entity that is associated with this ObjectStateEntry.
SalesOrderHeader associatedEnity = (SalesOrderHeader)stateEntry.Entity;
Console.WriteLine("Associated Enity's ID: {0}", associatedEnity.SalesOrderID);
}
2 голосов
/ 14 декабря 2011

Обычно хорошей практикой является использование самой структуры базы данных.Это просто еще один подход к тому, который у вас есть сейчас.

Вы можете создать новое поле типа datetime в таблице с именем, например, ModifiedOn и обновлять его каждый раз, когда вы обновляете строку вбаза данных.

Затем, когда вы хотите, чтобы измененные строки через определенное время вы просто используете:

where ModifiedOn > dateTime

Это просто еще одно предложение о том, как вы можете подойти к проблеме под другим углом.

...