C# 两个不同的POCO集合上的积垢
我有一个有趣的问题,我很难找到答案 我有两个IEnumerable对象集合。底层对象是完全独立的,但我可以识别一个应该匹配的共享键。集合很重要,因为我的“左”对象是“记录系统”,而“右”对象代表我需要确保与记录系统匹配的系统 一旦匹配,我需要在一侧执行CRUD操作,使右侧与左侧对齐。例如,如果右侧不存在一个项目,它将在右侧创建一个新项目;如果左侧缺少该项目,则更新值;如果右侧没有,则删除该项目 问题是,我有数百个这样的集合要匹配,而实际的CRUD代码是不同的 我想介绍一些共享代码,我可以在其中传入两个集合、集合类型(可能是泛型)、某种比较器,以及对CRUD执行什么操作的一些委托 如果这个代码确实存在,它可能看起来像这样C# 两个不同的POCO集合上的积垢,c#,generics,collections,delegates,compare,C#,Generics,Collections,Delegates,Compare,我有一个有趣的问题,我很难找到答案 我有两个IEnumerable对象集合。底层对象是完全独立的,但我可以识别一个应该匹配的共享键。集合很重要,因为我的“左”对象是“记录系统”,而“右”对象代表我需要确保与记录系统匹配的系统 一旦匹配,我需要在一侧执行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=