Необходимо сравнить 2 общих c списка одного типа на основе динамических c столбцов / полей, которые будут известны во время выполнения - PullRequest
0 голосов
/ 08 мая 2020

Я хочу сравнить 2 общих c списка одного типа на основе нескольких столбцов / полей, которые будут известны во время выполнения. Необходимо получить строки из второго списка, которых нет в первом списке, сопоставив заданные поля.

Сценарий:

public static void PerformCrudOperation<T>(List<T> sourceList, List<T> newList, 
    String [] columnNames) where T : class
{
    // list from sourceList that are not part of newList, matching criteria columnNames
}

например, у нас есть 2 списка типа «сотрудник» (но может быть любой type, поэтому требуется общее c решение)

class Employee
{
    public Int32 EmployeeID { get; set; }
    public String LastName { get; set; } 
    public String FirstName { get; set; } 
    public String Title { get; set; } 
    public String City { get; set; } 
    public String StatusFlag { get; set; } 
}
List<Employee> SourceList = new List<Employee>();
List<Employee> NewList = new List<Employee>();

SourceList находится в данных памяти.

NewList - это то, что пользователь предоставит, с некоторыми новыми записями, некоторыми измененными и некоторыми удаляемыми ( для удаления пользователь устанавливает StatusFlag для удаления).

Теперь ключи будут даваться с использованием, например, EmployeeID и LastName (но он также может добавить FirtName).

Цель: -1. Чтобы найти строки, которые необходимо удалить из SourceList \ 2. Чтобы определить новую строку для вставки (строки, которых нет в SourceList, путем сопоставления EmployeeID и LastName в обоих списках) 3. Измененная строка

Для получения дополнительной информации см.

1 Ответ

0 голосов
/ 09 мая 2020

Вы можете использовать отражение, чтобы перебирать все свойства для обоих элементов и определять, что вы хотите делать, когда указанные c свойства совпадают (или не совпадают).

Вот простой пример, который может помощь:

public static void PerformCrudOperation<T>(List<T> sourceList, List<T> newList,
    string[] columnNames) where T : class
{
    // Get a list of ALL the properties for the type
    List<PropertyInfo> props = typeof(T).GetProperties().ToList();

    // Get a list of just the properties from the column names array
    List<PropertyInfo> cols = props
        .Where(prop => columnNames.Contains(prop.Name)).ToList();

    // Get all items from source that don't have a corresponding item  
    // in newList that has all matching fields specified in columnNames
    var itemsToRemove = sourceList
        .Where(srcItem => !newList.Any(newItem => cols.All(col =>
            col.GetValue(srcItem) == col.GetValue(newItem))))
        .ToList();

    // Add any items that are in newList but don't 
    // have all colProps matching in sourceList
    var itemsToAdd = newList
        .Where(newItem => !sourceList.Any(srcItem => props.All(propInfo =>
            propInfo.GetValue(srcItem) == propInfo.GetValue(newItem))))
        .ToList();

    // Get all items from newList that have matching colProps in sourceList but 
    // different values for other properties
    var itemsToUpdate = newList
        .Where(newItem => sourceList.Any(srcItem =>
            cols.All(col => col.GetValue(newItem) == col.GetValue(srcItem)) &&
            props.Any(prop => prop.GetValue(newItem) != prop.GetValue(srcItem))))
        .ToList();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...