2016-12-06 1 views
1

Я пытаюсь объединить основной список клиентов с другим списком клиентов. Для каждого клиента я хочу сохранить значения из главного входного списка, если значение уже присутствует (но не null), иначе замените его соответствующим значением из другого списка.Слияние двух объектов и исключение нулевых значений в LINQ?

Что-то вроде этого:

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 свойств в моей сущности. Есть ли более простой способ сделать слияние, чем ручное кодирование всех 50 условных выражений в моем предложении select?

+0

Вы можете по крайней мере, сократить его 'Card_ID = a.Card_Id ?? b.Card_Id'. – juharr

ответ

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); 

Fiddle: https://dotnetfiddle.net/PlwXd3

Смежные вопросы