2016-03-10 4 views
1

У меня есть интересный вопрос: у меня возникли трудности в поиске ответа.CRUD над двумя различными коллекциями POCOs

У меня есть две IEnumerable коллекции объектов. Основные объекты полностью разделены, НО я могу определить общий ключ, который должен совпадать. Коллекции важны тем, что мой «левый» объект является «системой записи», а «правый» объект представляет собой систему, которую я должен обеспечить, чтобы соответствовать системе записи.

Как только они совпадают, мне нужно выполнить операции CRUD с одной стороны, чтобы привести правую сторону в линию с левой стороной. Например, он создавал бы новый элемент с правой стороны, если бы он не существовал или не обновлял значения или не удалялся, если элемент отсутствовал слева, но не был прав.

Уловка, у меня есть сотни этих коллекций, чтобы соответствовать, и фактический код CRUD отличается.

Я хотел бы ввести некоторый общий код, в котором я могу проходить в обеих коллекциях, типы коллекций (как, вероятно, generics), какой-то сравнитель и некоторые делегаты какой операции выполнять для CRUD.

Если этот код на самом деле существует, это может выглядеть примерно так

class Stuff 
{ 
    string Id {get; set;} 
    string Name {get; set;} 
} 

class Junk 
{ 
    string Id {get; set;} 
    string ShortName {get; set;} 
} 

IEnumerable<Stuff> myStuff = GetStuff(); 
IEnumerable<Junk> myJunk = GetJunk(); 

CrudComparer cc = new CrudComparer<Stuff, Junk>(myStuff, myJunk); 
cc.Comparer = (leftObject, rightObject) => { 
    leftObject.Name == rightObject.Name 
} 

cc.CreateOperation = (newObject, rightCollection) => { 
    Junk j = new Junk(); 
    j.Shortname = newObject.Name; 
    rightCollection.Add(j); 
} 

cc.UpdateOperation = (leftObject, rightObject) => { 
    rightObject.Shortname = leftObject.Name; 
} 

cc.DeleteOperation = (rightCollection, rightObject) => { 
    rightCollection.Remove(rightObject); 
} 

cc.Compare(); 

Кто-нибудь когда-нибудь видел код, который делает что-то вроде этого? Мне бы не хотелось изобретать колесо, если я могу схватить что-то уже сделанное.

Спасибо за помощь! --Michael

+0

Может хочет поставить этот вопрос на http://programmers.stackexchange.com/ –

+1

@roryap когда речь идет о других сайтах, часто бывает полезно указать, что [кросс-постинг неодобрения] (HTTP://meta.stackexchange.com/tags/cross-posting/info) – gnat

+0

@gnat - отметил, спасибо. –

ответ

0

Я подумал об этом и понял, что я знаю о дельтах и ​​дженериках, которых должно быть достаточно, чтобы решить эту проблему, поэтому я попал в LinqPad и немного повеселился. Я еще не писал никаких модульных тестов, поэтому используйте их на свой страх и риск, но, надеюсь, если вы хотите использовать это, вы поймете основные понятия.

class Blah 
{ 
    public int ID { get; set; } 
    public string BlahName { get; set;} 
} 

class Bleh 
{ 
    public int ID { get; set; } 
    public string BlehName { get; set;} 
} 

class CrudComparer<TLeft, TRight> 
{ 

    private readonly ICollection<TLeft> _leftCollection; 
    private readonly ICollection<TRight> _rightCollection; 
    private readonly Comparer _compareOperation; 
    private readonly CreateOperation _createOperation; 
    private readonly UpdateOperation _updateOperation; 
    private readonly DeleteOperation _deleteOperation; 

    public delegate bool Comparer(TLeft leftItem, TRight rightItem); 
    public delegate void CreateOperation(TLeft leftItem, ICollection<TRight> rightCollection); 
    public delegate void UpdateOperation(TLeft leftItem, TRight rightItem); 
    public delegate void DeleteOperation(TRight rightItem, ICollection<TRight> rightCollection); 

    public CrudComparer(ICollection<TLeft> leftCollection, ICollection<TRight> rightCollection, Comparer compareOperation, CreateOperation createOperation, UpdateOperation updateOperation, DeleteOperation deleteOperation) 
    { 
     _leftCollection = leftCollection; 
     _rightCollection = rightCollection; 
     _compareOperation = compareOperation; 
     _createOperation = createOperation; 
     _updateOperation = updateOperation; 
     _deleteOperation = deleteOperation; 
    } 

    public void Compare() 
    { 
     foreach (TLeft leftItem in _leftCollection) 
     { 
      bool foundItem = false; 
      foreach (TRight rightItem in _rightCollection) 
      { 
       if (_compareOperation(leftItem, rightItem)) 
       { 
        //these equal 
        foundItem = true; 
       } 
      } 

      if (foundItem == false) 
      { 
       _createOperation(leftItem, _rightCollection); 
      } 
     } 


     List<TRight> itemsToDelete = new List<TRight>(); 
     foreach (TRight rightItem in _rightCollection) 
     { 
      bool foundItem = false; 

      foreach (TLeft leftItem in _leftCollection) 
      { 
       if (_compareOperation(leftItem, rightItem)) 
       { 
        foundItem = true; 
        _updateOperation(leftItem, rightItem); 
        break;   
       } 
      } 

      if (!foundItem) 
      { 
       itemsToDelete.Add(rightItem); 
      } 
     } 

     foreach (TRight itemToDelete in itemsToDelete) 
     { 
      _deleteOperation(itemToDelete, _rightCollection); 
     } 
    } 
} 

void Main() 
{ 
    List<Blah> blahItems = new List<Blah>(); 
    blahItems.Add(new Blah() { ID = 1, BlahName = "Blah" }); 
    blahItems.Add(new Blah() { ID = 2, BlahName = "ABC" }); 
    blahItems.Add(new Blah() { ID = 34, BlahName = "XYZ" }); 
    blahItems.Add(new Blah() { ID = 6442, BlahName = "123" }); 

    List<Bleh> blehItems = new List<Bleh>(); 
    blehItems.Add(new Bleh() { ID = 2, BlehName = "12345"}); 
    blehItems.Add(new Bleh() { ID = 6, BlehName = "43232"}); 
    blehItems.Add(new Bleh() { ID = 77, BlehName = "BlahBlah"}); 
    blehItems.Add(new Bleh() { ID = 2334, BlehName = "ZYX"}); 

    CrudComparer<Blah, Bleh>.Comparer compareOperation = (leftObject, rightObject) => 
    { 
     return leftObject.ID == rightObject.ID; 
    }; 
    CrudComparer<Blah, Bleh>.CreateOperation createOperation = (leftObject, rightCollection) => 
    { 
     rightCollection.Add(new Bleh() { ID = leftObject.ID }); 
    }; 
    CrudComparer<Blah, Bleh>.UpdateOperation updateOperation = (leftObject, rightObject) => 
    { 
     rightObject.BlehName = leftObject.BlahName; 
    }; 
    CrudComparer<Blah, Bleh>.DeleteOperation deleteOperation = (rightObject, rightCollection) => 
    { 
     rightCollection.Remove(rightObject); 
    }; 

    CrudComparer<Blah, Bleh> cc = new CrudComparer<Blah, Bleh>(blahItems, blehItems, compareOperation, createOperation, updateOperation, deleteOperation); 
    cc.Compare(); 
} 
Смежные вопросы