2013-09-11 3 views
0

Это очень концептуальный вопрос, и я мог бы получить для этого. Но медведь со мной, пожалуйста.
У меня есть 2 List<myType>, содержащий иерархию данных в памяти из двух древовидных изображений. Один оригинал и один обновлены. myType имеет свойство объединения объектов, таким образом, структуру дерева.
В настоящее время я очищаю всю таблицу и сохраняю обновленный список в моей базе данных. Так как это не эффективно, как мне сравнить их и с сохранением изменений в моей базе данных?
Ниже приведен сценарий:Сохранение изменений только между двумя иерархическими списками

List<Person> tree1 = new List<Person>(); 
tree1.Add 
    (
     new Person() 
     { 
      Name = "Sr. John", 
      Age = 15, 
      People = new List<Person>() 
      { 
       new Person() 
       { 
        Name="John", 
        Age=10, 
        People=null 
       } 
      } 
     } 
    ); 


List<Person> tree2 = new List<Person>(); 
tree2.Add 
    (
     new Person() 
     { 
      Name = "Sr. John", 
      Age = 15, 
      People = new List<Person>() 
      { 
       new Person() 
       { 
        Name = "John", 
        Age = 10, 
        People = new List<Person>() 
        { 
         new Person() 
         { 
          Name = "Jr. John", 
          Age = 5, 
          People = null 
         } 
        } 
       } 
      } 
     } 
    ); 
+0

Как вы определяете, что 2 человека - это одно и то же лицо? Какова схема вашей базы данных? – nevermind

+0

У меня есть человек с одной таблицей с полем первичного ключа «Ссылка», а также «Имя» и «Возраст» и другое поле, которое EF генерирует для самостоятельного присоединения классов, которые «Reference_Person». Я просто хочу сказать, что объединить 2 списка, упомянутые выше, в один с изменениями, примененными к нему. – lbrahim

ответ

0

Предполагая, что вы не имеете несколько ссылок на один и тот же человек, вы можете использовать следующий алгоритм.

Это требует Person класса для реализации IEquatable интерфейса и возвращает true если 2 объекта идентификации тот же человек: иметь один и тот же Reference PK (если она заполнена в обоих деревах) или Name и Age; но сравнение должно игнорировать детей (не следует сравнивать People участник).

private static List<Person> EmptyList = new List<Person>(); 
void SaveDifference(List<Person> treeold, List<Person> treenew) 
{ 
    foreach(var pers in treenew) 
    { 
     int index = treeold.IndexOf(pers); 
     if(index >= 0) 
     { // node exists in both lists, check chlid nodes: 
      SaveDifference(treeold[index].People, pers.People); 
      treeold.RemoveAt(index); 
     } 
     else 
     { // new added node 
      // TODO: Store 'pers' to database (and update references in parent) 
      SaveDifferences(EmptyList, pers.People) 
     } 
    } 

    foreach(var pers in treeold) 
    { // node was deleted 
     SaveDifferences(pers.People, EmptyList); 
     // TODO: remove 'pers' from DB (and update references in parent) 
    } 
} 
+0

Спасибо за ответ. Но на самом деле я не понял этого. Когда я реализую 'IEquatable', он дает мне метод« Equals (Type other) ». Не могли бы вы объяснить немного больше? – lbrahim

+0

Метод 'SaveDifference' выше использует метод IndexOf, чтобы найти человека из« нового »списка в« старом »списке. В методе 'IndexOf' используется' EqualityComparer .Default' (см. MSDN), который, в свою очередь, использует 'IEquatable .Equals', чтобы определить, представляют ли 2 заданных объекта из списков одно и то же лицо. F.i., в вашем примере кода вы создали * 2 разных экземпляра * из 'Sr. John', поэтому метод по умолчанию будет сравнивать * ссылки * и возвращать false. Поэтому вам необходимо предоставить метод Equals, который будет сравнивать поля, которые однозначно идентифицируют человека (например, поле «Имя»). – nevermind

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