С# объединить два объекта вместе во время выполнения
У меня есть ситуация, когда я загружаю очень ненормализованный набор записей из Excel. Я втягиваю каждую строку и создаю из нее объекты по одному. каждая строка может содержать компанию и/или клиента.
Моя проблема в том, что несколько строк могут иметь одни и те же объекты, поэтому я, возможно, уже создал их. Я делаю сравнение, чтобы узнать, есть ли он в списке. Если это так, мне нужно объединить два объекта, чтобы убедиться, что я не получил никакой новой информации из второй строки.
так:
company - client - address - phone
----------------------------------------
mycompany - - myaddress -
mycompnay - myclient - - myphone
поэтому первая строка создаст объект компании с адресом "myaddress".
Вторая строка создала бы другой объект компании (который по моим правилам является той же самой компанией, что и имя одного и того же), это также имеет ссылку клиента и номер телефона.
Поэтому я бы знал, что они одинаковы, но нужно обеспечить, чтобы все данные были объединены в один объект.
В настоящий момент я создаю класс утилиты, который принимает оба объекта (один из которых является первичным, а другой - объединенным, поэтому имеет приоритет, если есть столкновение), он проходит через каждую переменную и присваивает значения if есть. Это небольшая плита бойлера, и я надеялся, что может быть какая-то полезность, которую я мог бы использовать, чтобы выполнить ручную работу для меня.
Пример упрощен, так как есть несколько других переменных, некоторые основные типы и другие, которые являются более сложными элементами.
Ответы
Ответ 1
Отражение будет работать. Что-то вроде:
public static void MergeWith<T>(this T primary, T secondary) {
foreach (var pi in typeof(T).GetProperties()) {
var priValue = pi.GetGetMethod().Invoke(primary, null);
var secValue = pi.GetGetMethod().Invoke(secondary, null);
if (priValue == null || (pi.PropertyType.IsValueType && priValue.Equals(Activator.CreateInstance(pi.PropertyType)))) {
pi.GetSetMethod().Invoke(primary, new object[]{secValue});
}
}
}
Ответ 2
Я бы попытался разбить это: разделите и победите.
Сначала прочитайте все объекты в одном огромном списке.
На втором этапе выберите отдельные списки, используя ваш первичный ключ, например название компании. В отдельном списке используйте элемент (мастер) с наибольшим количеством заданных полей. Затем повторите все поля, которые еще не находятся в главном файле, и объедините их значения. LINQ поможет вам во многих этих шагах без необходимости кодирования сложных алгоритмов вручную.
Это позволяет легко настроить логику позже, например. если у вас есть другой набор "первичных ключей", так сказать, или если вы хотите выполнять специальные сравнения отдельных полей.
Ответ 3
Я пробовал Слияние двух объектов в анонимный тип от Kyle Finley и работает отлично.
С TypeMerger
слияние так же просто, как
var obj1 = new {foo = "foo"};
var obj2 = new {bar = "bar"};
var mergedObject = TypeMerger.MergeTypes(obj1 , obj2 );
Чтобы у вас был объединенный объект, кроме этого, есть условие для игнорирования определенных свойств.
Ответ 4
Попробуйте создать хеш-таблицу на основе строк. Используйте конкатенацию подмножества полей, которые вы считаете триггером для дублирующей записи в качестве ключа. Хэш-таблица не позволяет дублировать, поэтому вы можете использовать эту ошибку в качестве триггера для дальнейшей обработки.
Ответ 5
Не зная намного больше о вашей среде и требованиях, это может быть бесполезно. Но если у вас есть доступ к какой-либо базе данных (даже для клиентских сторон), вы можете хранить данные в таблице и использовать SQL Merge для обновления данных. Операция слияния либо добавит, либо обновит запись по мере необходимости. Триггер может дополнительно уточнить операцию. Это довольно тяжелое решение, но если у вас уже есть СУБД в миксе, это может быть простой способ его реализации.
Ответ 6
Когда вы извлекаете данные из Excel, нет необходимости создавать объект для каждой строки. Фактически, вы, вероятно, захотите перейти к промежуточной форме, которая считывает все строки вверх, а затем создает объекты оттуда. Решение Киббей с использованием хэш-таблиц также могло бы работать здесь.