2015-08-18 3 views
1

Я пытаюсь объединить данные из двух отдельных запросов с помощью C#. Данные расположены на отдельных серверах, или я просто хотел бы объединить запросы. Я хочу обновить данные в одном из столбцов первого набора данных с данными в одном из столбцов второго набора данных, соединяясь с другим столбцом.Как использовать LINQ для обновления datatable с помощью SqlDataReader?

Вот то, что я до сих пор:

ds.Tables[3].Columns[2].ReadOnly = false; 
List<object> table = new List<object>(); 
table = ds.Tables[3].AsEnumerable().Select(r => r[2] = reader.AsEnumerable().Where(s => r[3] == s[0])).ToList();  

ToList() только для отладки. Подводя итог, ds.Tables[3].Rows[2] - это столбец, который я хочу обновить. ds.Tables[3].Rows[3] содержит ключ, к которому я хочу присоединиться.

В считывателе первый столбец содержит ключ соответствия ds.Tables[3].Rows[3], а второй столбец содержит данные, которые я хочу обновить ds.Tables[3].Rows[2].

Ошибка я получаю это

Невозможно привести объект типа «WhereEnumerableIterator 1[System.Data.IDataRecord]' to type 'System.IConvertible'.Couldn't store <System.Linq.Enumerable+WhereEnumerableIterator 1 [System.Data.IDataRecord]> в Цитирование дилеров Колонна. Ожидаемый тип - Int32.

Где я иду не так с моей LINQ?

EDIT:

Я обновил линию, где обновление происходит

table = ds.Tables[3].AsEnumerable().Select(r => r[2] = reader.AsEnumerable().First(s => r[3] == s[0])[1]).ToList();

но теперь я получаю

последовательность не содержит соответствующий элемент

Для запись, последовательность содержит соответствующий элемент.

+2

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

+0

Linq для _querying_, а не _updating_. Вы пытаетесь создать запрос Linq, который имеет побочные эффекты в 'Select', который не является правильным использованием Linq. Вместо этого вы должны использовать традиционный цикл 'for' или' foreach'. –

+0

@ DStanley это плохая практика использования LINQ для обновления? Я сделал это в прошлом. Я предпочитаю его «foreach», потому что он более краткий. Я знаю, как это сделать с операторами 'foreach', но я хочу использовать LINQ, в частности, для обозначения точек. – Adam

ответ

1

Для достижения операции объединения и обновления вы можете использовать следующий образец. Давайте предположим, что есть два DataTables:

tbl1: tbl1

tbl2: tbl2

Объединение двух таблиц и обновление значения столбца "имя1" из tbl1 из колонки "имя2" от tbl2.

public DataTable JoinAndUpdate(DataTable tbl1, DataTable tbl2) 
{ 
    // for demo purpose I have created a clone of tbl1. 
    // you can define a custom schema, if needed. 
    DataTable dtResult = tbl1.Clone(); 

    var result = from dataRows1 in tbl1.AsEnumerable() 
       join dataRows2 in tbl2.AsEnumerable() 
       on dataRows1.Field<int>("ID") equals dataRows2.Field<int>("ID") into lj 
       from reader in lj 
       select new object[] 
        { 
        dataRows1.Field<int>("ID"), // ID from table 1 
        reader.Field<string>("name2"), // Updated column value from table 2 
        dataRows1.Field<int>("age") 
        // .. here comes the rest of the fields from table 1. 
        }; 

    // Load the results in the table 
    result.ToList().ForEach(row => dtResult.LoadDataRow(row, false)); 

    return dtResult; 
} 

Вот результат:

resulting table after updation

+0

Сначала я бы создал список результатов (в виде списка 'object []' s), а затем загрузил datatable. Методы Linq не должны иметь побочных эффектов, и теперь роль «ToList» несколько неясна. –

0

После рассмотрения того, что сказал @DStanley о LINQ, я оставил его и пошел с foreach заявление.См. Код ниже:

ds.Tables[3].Columns[2].ReadOnly = false; 
while (reader.Read()) 
{ 
    foreach (DataRow item in ds.Tables[3].Rows) 
    { 
     if ((Guid)item[3] == reader.GetGuid(0)) 
     { 
      item[2] = reader.GetInt32(1); 
     } 
    } 
} 
Смежные вопросы