合并两个实体并消除LINQ中的空值?

时间:2016-12-06 22:46:39

标签: c# .net linq join

我正在尝试将主客户列表与另一个客户列表合并。对于每个客户,如果值已经存在(非空),我想保留主输入列表中的值,否则将其替换为其他列表中的相应值。

这样的事情:

public class Customer
{
    public int ID { get; set; }

    public string Card_ID { get; set; }

    public decimal? Cash { get; set; }
}


var masterlist = new List<Customer>()
{
    new Customer() { ID = 1, Cash = 25 },
    new Customer() { ID = 2, Card_ID = "card2" }
};

var existinglist = new List<Customer>()
{
    new Customer() { ID = 1, Card_ID = "card1" },
    new Customer() { ID = 2, Card_ID = "card12222222222", Cash = 27 }
};

var mergedlist = (from a in masterlist
                  from b in existinglist
                  where a.ID == b.ID
                  select new
                  {
                      ID = a.ID,
                      Card_ID = (a.Card_ID == null ? b.Card_ID : a.Card_ID),
                      Cash = a.Cash.HasValue ? a.Cash : b.Cash
                  }).ToList();

合并列表中的预期结果如下:

{ ID = 1, Card_ID = "card1", Cash = 25 }  
{ ID = 2, Card_ID = "card2", Cash = 27 }

现在我的观点是,我的实体中有超过50个属性。有没有更简单的方法来进行合并,而不是手工编码我的select子句中的所有50个条件?

1 个答案:

答案 0 :(得分:2)

您可以创建一个基于反射的辅助方法来合并一对相似对象的属性:

public static T Merge<T>(T master, T other) where T : new()
{
    var properties = typeof(T).GetProperties()
        .Where(p => p.CanRead && p.CanWrite && !p.GetIndexParameters().Any());

    T result = new T();

    foreach (var prop in properties)
    {
        object value = prop.GetValue(master) ?? prop.GetValue(other);
        prop.SetValue(result, value);
    }

    return result;
}

然后,使用帮助器方法加入列表,在每对上进行合并:

var mergedlist = from a in masterlist
                 join b in existinglist 
                 on a.ID equals b.ID
                 select Merge(a, b);

小提琴:https://dotnetfiddle.net/PlwXd3