对两个不同的 POCO 集合进行 CRUD



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

我有两个 IE无数的对象集合。 底层对象是完全独立的,但我可以识别应该匹配的共享密钥。 集合很重要,因为我的"左"对象是"记录系统",而"右"对象表示我需要确保与记录系统匹配的系统。

匹配后,我需要在一侧执行 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();

有没有人见过做这样事情的代码? 如果我能抓住已经完成的事情,我不想重新发明轮子。

感谢您的任何帮助!--迈克尔

我开始更多地思考这个问题,并意识到我对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();
}

相关内容

  • 没有找到相关文章

最新更新