2013-03-19 2 views
0

Я нахожусь на этом.Linq, объединяющий DataTable с динамически добавленными первичными ключами

Я пытаюсь объединить два DataTable s в один. Я хотел бы использовать linq для выполнения этой задачи, но проблема в том, что мне нужно добавить условия для объединения динамически. Данные для каждой таблицы поступают из двух разных вызовов хранимых процедур и используемых вызовов. Результаты могут варьироваться в зависимости от количества столбцов и доступных первичных ключей.
Целью является замена обычных строк в первом наборе результатов со второй базой данных, которая может содержать unicode (но только если она содержит значение для этой конкретной комбинации первичных ключей).

Моего LINQ запрос будет выглядеть следующим образом:

var joined = (from DataRow reg in dt1.Rows 
       join DataRow uni in dt2.Rows 
        on new { prim1 = reg.ItemArray[0], prim2 = reg.ItemArray[1] } 
        equals new { prim1 = uni.ItemArray[0], prim2 = uni.ItemArray[1] } 
       select new 
        { 
         prim1 = reg.ItemArray[0], 
         prim2 = reg.ItemArray[1], 
         value1 = reg.ItemArray[4], 
         value2 = uni.ItemArray[3] ?? reg.ItemArray[3] 
        } 
       ); 

Это отлично работает для того, что я хочу, но как я сказал, что я должен быть в состоянии определить, какие столбцы в каждой таблице, являются первичными ключами, так это:

join DataRow uni in dt2.Rows 
        on new { prim1 = reg.ItemArray[0], prim2 = reg.ItemArray[1] } 
        equals new { prim1 = uni.ItemArray[0], prim2 = uni.ItemArray[1] } 

должен быть заменен чем-то вроде создания DataRelation между таблицами или перед выполнением linq добавления первичных ключей динамически.

ТАКЖЕ, мне нужно сделать что-то вроде выбора SQLs * вместо указания каждого столбца, так как я не знаю, число столбцов в первом наборе результатов.

Я также попытался присоединиться к таблицам, добавив первичные ключи и выполнив слияние, но как я могу выбрать, какой столбец в dt2 переписать в dt1?

DataTable join = new DataTable("joined"); 
join = dt1.Copy(); 
join.Merge(dt2, false, MissingSchemaAction.Add); 
join.AcceptChanges(); 

Я пользуюсь VS2012.

ответ

0

В итоге я использовал очень простой подход, который не предполагает создания отношений первичного ключа или объединения вообще. Я уверен, что есть более элегантные или эффективные способы решения проблемы.

В основном я адаптировал решение в Linq dynamically adding where conditions, где вместо соединения я динамически добавляю .Where -clauses.

Таким образом, я могу цикл по строкам и сравнить для каждого динамически добавленного первичного ключа:

foreach (DataRow regRow in dt1.Rows) 
{ 
    //Select all rows in second result set 
    var uniRows = (from DataRow uniRow in dt2.Rows select uniRow); 
    //Add where clauses as needed 
    if (firstCondition) { uniRows = uniRows.Where(x => x["SalesChannel"] == "001"); } 
    else if (secondCondition) { uniRows = uniRows.Where(x => x["Language"] == "SV"); } 
    else (thirdCondition) { uniRows = uniRows.Where(x => x["ArticleNo"] == "242356"); } 
    // etc... 
} 

Каждая строка получает сравнивается со списком уменьшающейся строк во втором наборе результатов.

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