Страницы

Поиск по вопросам

пятница, 10 января 2020 г.

Аналог в LINQ для SELECT * FROM table1 INNER JOIN table2

#c_sharp #linq


Есть два объекта DataTable datatable1 и datatable2. Как получить на выходе результат
LINQ запроса аналогичный SQL-ному SELECT * FROM table1 INNER JOIN table2 ON condition
в новом объекте DataTable? Как делать сам INNER JOIN и даже OUTER JOIN ясно. 

from table1 in datatable1.AsEnumerable()
  join table2 in datatable2.AsEnumerable() 
  on (int)table1["anID"] equals                
     (int)table2["anID"]
  select new
  {
     A = (int)table1["A"],
     B = (int)table1["B"],
     C = (int)table2["C"],
     D = (int)table2["D"]
  };


А вот как получить результат в новом DataTable, не перечисляя при этом поля пример
не попадается.

P.S. Вопрос не о работе с БД, а о возможностях c# + linq
    


Ответы

Ответ 1



Так как нужна именно DataTable, то первоначально нужно создать ее и добавить колонки. Судя из вопроса вы хотите добавить все колонки из первой таблицы и из второй. Для этого можно воспользоваться следующим кодом. DataTable table = new DataTable(); foreach(DataColumn column in table1.Columns){ table.Columns.Add("table1_"+column.ColumnName, column.DataType) } foreach(DataColumn column in table2.Columns){ table.Columns.Add("table2_"+column.ColumnName, column.DataType) } Теперь в новой таблице колонки из обеих таблиц и можно добавлять строки. var rows = from table1 in datatable1.AsEnumerable() join table2 in datatable2.AsEnumerable() on (int)table1["anID"] equals (int)table2["anID"] select table1.itemArray.Concat(table2.itemArray); Получили список массивов которые можно добавлять в DataTable. foreach(var row in rows){ table.Rows.Add(row); } В итоге получили table со всеми нужными строками.

Ответ 2



Для объединения таблиц можно использовать метод DataTable.Merge Например, есть таблица t1: id c11 ----------- 1 11 и таблица t2: id c21 ----------- 1 21 Для того чтобы объединить эти таблицы пишем var t3 = new DataTable("t3"); t3.Merge(t1); t3.Merge(t2); Результат id c11 c21 ------------------- 1 11 - 1 - 21 Код для примера // #r "System.Data" using System.Data; DataTable table(string name, params DataColumn[] columns) { var t = new DataTable(); t.Columns.Add(new DataColumn("id", typeof(int)) { AutoIncrement=true, Unique=true }); foreach (var c in columns) t.Columns.Add(c); return t; } void print(DataTable t) { Console.WriteLine( String.Join( "\t\t", t.Columns.OfType().Select(c => c.ColumnName))); foreach (var r in t.Rows.OfType()) Console.WriteLine( String.Join( "\t\t", r.ItemArray.Select(v => v != DBNull.Value ? v : "-"))); } var t1 = table("t1", new DataColumn("c11", typeof(int))); var t2 = table("t2", new DataColumn("c21", typeof(int))); t1.Rows.Add(1, 11); print(t1); t2.Rows.Add(1, 22); print(t2); var t3 = new DataTable("t3"); t3.Merge(t1, true); t3.Merge(t2, true); print(t3);

Ответ 3



Хороший ответ на вопрос есть вот тут: https://stackoverflow.com/questions/15215233/return-all-columns-in-anonymous-linq-join Т.е. выборку осуществляем вот так: var result = (from table1 in datatable1.AsEnumerable() join table2 in datatable2.AsEnumerable() on (int)table1["anID"] equals (int)table2["anID"] into allColumns from rows in allColumns select new { first = table1, second = rows }); А данные обрабатываем вот так: foreach (var item in result) { Console.WriteLine ( "{0} {1}", item.first["Имя колонки из 1-й таблицы"], item.second["Имя колонки из 2-й таблицы"] ); }

Комментариев нет:

Отправить комментарий