У меня есть следующие две таблицы, которые импортируются из файлов Excel в мое приложение Windows Forms. Эти файлы создаются автоматически, и, к сожалению, их невозможно изменить. Я упростил все примеры ниже. На самом деле таблицы имеют более 40 столбцов и более 100 тыс. Строк в каждой.
Первая таблица содержит информацию о счетах клиента, где customer - это номер клиента, который я использую в качестве первичного ключа.
BillingTable
Customer(PK) Name Address Type
------------ ------------- ---------- -----------
1 Customer 1 Address 1 Billing
2 Customer 2 Address 2 Billing
3 Customer 3 Address 3 Billing
Вторая таблица содержит информацию о доставке клиента и имеет другой номер клиента. В столбце «Партнер» указана платежная информация:
ShippingTable
Customer Name Address Type Partner(PK)
--------- ----------- -------------- ---------- ------------
4 Customer 1 Sh.Address 1 Shipping 1
5 Customer 2 Sh.Address 2 Shipping 2
6 Customer 4 Sh.Address 4 Shipping 6
Как видите, в таблице информации для выставления счета есть записи, на которые нет ссылки в таблице информации о доставке. Также бывает, что у клиента есть информация о доставке, но нет информации о счете. В этом случае в столбце партнера содержится номер клиента из таблицы с информацией о доставке.
Я должен объединить обе таблицы в следующее:
ResultTable
Customer(PK) Shipping Name Address Type
------------- ----------- ------------ ------------ ----------
1 4 Customer 1 Address 1 Billing
2 5 Customer 2 Address 2 Billing
3 Customer 3 Address 3 Billing
6 6 Customer 4 Sh.Address 4 Shipping
Так что мне нужна таблица, в которой только номер покупателя добавляется в таблицу счетов, если он есть. Если нет, столбец доставки может остаться пустым. Если есть информация о доставке, но нет информации о счете, я хотел бы получить всю строку из таблицы ShippingTable.
При простом использовании метода DataTable.Merge()
, например BillingTable.Merge(ShippingTable)
, столбцы адреса и типа таблицы расчета заменяются информацией о доставке. При установке для preserveChanges значения true, такого как BillingTable.Merge(ShippingTable, true)
, он не объединяет номера клиентов доставки в таблицу BillingTable, а просто добавляет дополнительную информацию о клиенте доставки в таблицу.
Я также пытался «вручную» получить номер доставки для каждой строки, зацикливая их и используя Linq для получения необходимой информации о доставке. Но так как я работаю с огромным количеством строк, это занимает очень много времени.
Следующее, что я попытался, это удалить столбец Address and Type из ShippingTable перед объединением. Но в этом случае, конечно, я теряю информацию клиентов, которые не имеют платежной информации.
Итак, чтобы подвести итог, я попробовал вот что:
BillingTable.Merge(ShippingTable); // Billing info is overwritten
BillingTable.Merge(ShippingTable, true); // Does not merge shipping number
// Loop through each row, takes very long
foreach(DataRow row in BillingTable.Rows) {
row["Shipping"] = ShippingTable.Rows.Cast<DataRow>()
.Where(shRow => shRow["Partner"].ToString() == row["Customer"])
.First()
.Field<string>("Customer");
}
// Delete Address and Type columns before merging
// Does not include address and type information for shipping only entries
ShippingTable.Columns.Remove("Address");
ShippingTable.Columns.Remove("Type");
BillingTable.Merge(ShippingTable);
А вот и результаты:
С BillingTable.Merge (ShippingTable)
Customer(PK) Shipping Name Address Type
------------- ----------- ------------ ------------- ---------
1 4 Customer 1 Sh.Address 1 Shipping
2 5 Customer 2 Sh.Address 2 Shipping
3 Customer 3 Address 3 Billing
6 6 Customer 4 Sh.Address 4 Shipping
С BillingTable.Merge (ShippingTable, true)
Customer(PK) Shipping Name Address Type
------------- ------------ ------------ ------------- ---------
1 Customer 1 Address 1 Billing
2 Customer 2 Address 2 Billing
3 Customer 3 Address 3 Billing
6 6 Customer 4 Sh.Address 4 Shipping
При удалении столбца «Адрес» и «Тип» из ShippingTable перед объединением:
Customer(PK) Shipping Name Address Type
------------- ----------- ------------ ------------ ----------
1 4 Customer 1 Address 1 Billing
2 5 Customer 2 Address 2 Billing
3 Customer 3 Address 3 Billing
6 6
Так что либо существует способ объединения таблиц, который я до сих пор не смог найти, либо мне придется сделать это другим способом. Я думал о присоединении таблиц с помощью SQL при получении их из файлов Excel или о присоединении таблиц с помощью Linq вместо DataTable.Merge()
, но я не смог найти ни одного способа для правильной работы.
Может кто-нибудь помочь, пожалуйста?
(простите за длинное описание)