2013-08-29 3 views
9

Я прочесали интернет, чтобы попытаться найти решение для этого, и, возможно, я не собираюсь этого делать правильно.Сравните два набора данных - найдите изменения - LINQ

Мне нужно сравнить два набора данных, идентичных по структуре, и хотели бы найти новые и измененные объекты (используя LINQ).

Используя то, что я нашел на CodeProject, мне удалось собрать список элементов, которые были изменены, но это было сделано путем жесткого кодирования каждого столбца (и их будет много) и проверки одинаковых значений:

var updRec = from u in updated 
      join o in orig 
       on u.KeyValue equals o.KeyValue 
      where 
       (o.Propery1 != u.Propery1) || 
       (o.Propery2 != u.Propery2) 
      select new record 
      { 
       KeyValue = u.KeyValue, 
       Propery1 = u.Propery1, 
       Propery2 = u.Propery2 , 
       RecordType = "mod" // Modified 
      }; 

Я мог бы использовать помощь 2 вещи:

  1. есть ли более эффективный способ перебора каждого из столбцов, как я планирую добавить много больше свойств, что мне нужно, чтобы сравнить ? Должен быть лучший способ динамически проверять 2 идентичных набора данных для изменений.
  2. Как я могу видеть , который недвижимости изменился? Например, создавая список «Свойство, оригиналValue, UpdateValue» для всех элементов, которые не идентичны?

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

+0

Вы можете переопределить 'Equals()' в вашем объекте 'record' и выполнить сравнение там. Затем вы можете изменить предложение 'where' на' where o.Equals (u) '. Но это просто переводит сравнение в более инкапсулированное место. Если вы хотите больше автоматизации, вам, вероятно, придется использовать отражение. –

+0

Возможно, вам придется перечислить все столбцы, возможно, я просто не знаю лучшего способа, но я знаю, что в TSQL вам нужно перечислить все столбцы для сравнения дельт, хотя для более быстрого сравнения есть некоторые групповые трюки. –

+0

Как вы определяете изменение? Я недавно наткнулся на аналогичную проблему, и я создал метод, который объединяет 2 объекта одного типа, принимая значение от объекта, свойство которого не равно null или по умолчанию, а также предоставляет возможность выбора приоритетного объекта, в случае оба свойства имеют значение. Если это то, что вам может понадобиться, сообщите мне, и я отправлю ответ с кодом и более подробным объяснением. –

ответ

0
  1. Более быстрый, но вам нужно будет поддерживать код, если вы добавляете новые свойства, это написать пользовательский сопоставитель и использовать свой подход.
  2. Медленнее использование отражение пройти через все свойства и сравнить их динамически

    IDictionary<string, Tuple<object, object>> GetDifferentProperties<T>(T keyValue1, T keyValue2) 
    { 
        var diff = new Dictionary<string, object>(); 
        foreach (var prop in typeof(T).GetProperties(BindingFlags.Public)) 
        { 
         var prop1Value = prop.GetValue(keyvalue1); 
         var prop2Value = prop.GetValue(keyValue2); 
         if (prop1Value != prop2Value) 
         diff.Add(prop.Name, Tuple.Create(prop1Value, prop2Value)); 
        } 
        return diff; 
    } 
    

, а затем в вас код

var = results = (from u in updated 
        join o in orig 
        select new 
        { 
         Value1 = o.KeyValue, 
         Value2 = u.KeyValue 
        }).ToArray() 
        .Select(x => GetDifferentProperties(x.Value1, x.Value2)) 
        .Select(DoSomestufWithDifference); 
1

Вы можете использовать LINQ Кроме метода расширения(). Это возвращает все в списке, кроме того, что находится во втором списке.

var orignalContacts = GetOrignal(); 
var updatedContacts = GetUpdated(); 

var changedAndNew = updatedContacts.Except(orignalContacts); 
var unchanged  = orignalContacts.Except(updatedContacts); 

В зависимости от поставщика данных может потребоваться overide Equals() и GetHashCode() на ваших объектах.

Смежные вопросы