C# 两个不同的POCO集合上的积垢

C# 两个不同的POCO集合上的积垢,c#,generics,collections,delegates,compare,C#,Generics,Collections,Delegates,Compare,我有一个有趣的问题,我很难找到答案 我有两个IEnumerable对象集合。底层对象是完全独立的,但我可以识别一个应该匹配的共享键。集合很重要,因为我的“左”对象是“记录系统”,而“右”对象代表我需要确保与记录系统匹配的系统 一旦匹配,我需要在一侧执行CRUD操作,使右侧与左侧对齐。例如,如果右侧不存在一个项目,它将在右侧创建一个新项目;如果左侧缺少该项目,则更新值;如果右侧没有,则删除该项目 问题是,我有数百个这样的集合要匹配,而实际的CRUD代码是不同的 我想介绍一些共享代码,我可以在其中传

我有一个有趣的问题,我很难找到答案

我有两个IEnumerable对象集合。底层对象是完全独立的,但我可以识别一个应该匹配的共享键。集合很重要,因为我的“左”对象是“记录系统”,而“右”对象代表我需要确保与记录系统匹配的系统

一旦匹配,我需要在一侧执行CRUD操作,使右侧与左侧对齐。例如,如果右侧不存在一个项目,它将在右侧创建一个新项目;如果左侧缺少该项目,则更新值;如果右侧没有,则删除该项目

问题是,我有数百个这样的集合要匹配,而实际的CRUD代码是不同的

我想介绍一些共享代码,我可以在其中传入两个集合、集合类型(可能是泛型)、某种比较器,以及对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();
类内容
{
字符串Id{get;set;}
字符串名称{get;set;}
}
班级垃圾
{
字符串Id{get;set;}
字符串短名称{get;set;}
}
IEnumerable myStuff=GetStuff();
IEnumerable myJunk=GetJunk();
CrudComparer cc=新的CrudComparer(myStuff,myJunk);
cc.Comparer=(leftObject,rightObject)=>{
leftObject.Name==rightObject.Name
}
cc.CreateOperation=(newObject,rightCollection)=>{
垃圾j=新垃圾();
j、 Shortname=newObject.Name;
右侧集合。添加(j);
} 
cc.UpdateOperation=(leftObject,rightObject)=>{
rightObject.Shortname=leftObject.Name;
}
cc.DeleteOperation=(rightCollection,rightObject)=>{
rightCollection.Remove(rightObject);
}
cc.Compare();
有人见过这样的代码吗?如果我能抓住已经做过的事情,我就不想重新发明轮子

谢谢你的帮助!
--Michael

我开始更多地思考这个问题,并意识到我对delgates和泛型的了解应该足以解决这个问题,所以我进入了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();
}
class废话
{
公共int ID{get;set;}
公共字符串BlahName{get;set;}
}
类气泡
{
公共int ID{get;set;}
公共字符串BlehName{get;set;}
}
阶级比较
{
私有只读ICollection\u leftCollection;
私有只读ICollection\u rightCollection;
专用只读比较器\u compareOperation;
私有只读CreateOperation _CreateOperation;
私有只读更新操作\u更新操作;
私有只读删除操作_DeleteOperation;
公共委托布尔比较器(TLeft-leftItem、TRight-rightItem);
公共委托void CreateOperation(TLeft leftItem、ICollection rightCollection);
公共委托无效更新操作(TLeft leftItem、TRight RIGHT ITEM);
公共委托无效删除操作(TRight rightItem、ICollection rightCollection);
公共CrudComparer(ICollection leftCollection、ICollection rightCollection、Comparer compareOperation、CreateOperation CreateOperation、UpdateOperation UpdateOperation、DeleteOperation DeleteOperation)
{
_leftCollection=leftCollection;
_rightCollection=rightCollection;
_比较操作=比较操作;
_createOperation=createOperation;
_updateOperation=updateOperation;
_deleteOperation=deleteOperation;
}
公共空间比较()
{
foreach(左集合中的左项)
{
bool foundItem=false;
foreach(TRight rightItem在_rightCollection中)
{
if(_compareOperation(leftItem,rightItem))
{
//这些相等
foundItem=true;
}
}
if(foundItem==false)
{
_createOperation(leftItem,_rightCollection);
}
}
List itemsToDelete=新列表();
foreach(TRight rightItem在_rightCollection中)
{
bool foundItem=false;
foreach(左集合中的左项)
{
if(_compareOperation(leftItem,rightItem))
{
foundItem=true;
_更新操作(leftItem、rightItem);
打破
}
}
如果(!foundItem)
{
itemsToDelete.Add(右项);
}
}
foreach(在itemsToDelete中触发itemToDelete)
{
_删除操作(itemToDelete,_rightCollection);
}
}
}
void Main()
{
List blahItems=新列表();
Add(新Blah(){ID=1,BlahName=“Blah”});
Add(新的Blah(){ID=2,BlahName=“ABC”});
Add(新Blah(){ID=34,BlahName=“XYZ”});
Add(新的Blah(){ID=6442,BlahName=“123”});
List blehItems=新列表();
Add(新的Bleh(){ID=2,BlehName=“12345”});
Add(新的Bleh(){ID=6,BlehName=“43232”});
Add(新的Bleh(){ID=77,BlehName=“BlahBlah”});
Add(新的Bleh(){ID=2334,BlehName=“ZYX”});
CrudComparer.Comparer compareOperation=(leftObject,rightObject)=>
{ 
返回leftObject.ID==rightObject.ID;
};
CrudComparer.CreateOperation CreateOperation=(leftObject,rightCollection)=>
{ 
Add(new Bleh(){ID=leftObject.ID});
};
CrudComparer.UpdateOperation UpdateOperation=(leftObject,rightObject)=>
{
rightObject.BlehName=leftObject.BlahName;
};
CrudComparer.DeleteOperation DeleteOperation=