Как быстро объединить две таблицы данных, используя linq без имен столбцов - PullRequest
0 голосов
/ 04 июля 2018

На этот вопрос, вероятно, ответили где-то еще, но я еще не нашел работающего решения.

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

Я не хочу перечислять все столбцы (всего 180) из первого набора данных. Я пробовал например. это

var JoinedResult = from t1 in table1.Rows.Cast<DataRow>()
                   join t2 in table2.Rows.Cast<DataRow>() 
                      on Convert.ToInt32(t1.Field<string>("ProductID")) equals t2.Field<int>("FuelId")
                    select t1;

но это дает только столбцы из таблицы1. Как получить столбцы из table2 тоже к моему результату? Наконец, мне нужно добавить свой результат в набор данных.

ResultSet.Tables.Add(JoinedResult.CopyToDataTable());

EDIT:

Я остановился на этом как на решении. Это следует примеру, приведенному здесь Создание объединения с помощью Выбрать все (выбрать *) в linq для наборов данных

 DataTable dtProduct = dsProduct.Tables[0];
 DataTable dtMoistureLimits = ds.Tables[0];

 //clone dt1, copies all the columns to newTable 
 DataTable dtProductWithMoistureLimits = dtProduct.Clone();

 //copies all the columns from dt2 to newTable 
foreach (DataColumn c in dtMoistureLimits.Columns)
   dtProductWithMoistureLimits.Columns.Add(c.ColumnName, c.DataType);

   var ProductsJoinedWithMoistureLimits = dtProduct.Rows.Cast<DataRow>()
       .Join(dtMoistureLimits.Rows.Cast<DataRow>(),// join table1 and table2
       t1 => new { ProductID = t1.Field<int>("ProductID"), DelivererID = t1.Field<int>("DelivererID") },
       t2 => new { ProductID = t2.Field<int>("MoistureLimits_ProductID"), DelivererID = t2.Field<int>("MoistureLimits_DelivererID") },
       (t1, t2) =>     // when they match 
       {    // make a new object
            // containing the matching t1 and t2
           DataRow row = dtProductWithMoistureLimits.NewRow();
           row.ItemArray = t1.ItemArray.Concat(t2.ItemArray).ToArray();
           dtProductWithMoistureLimits.Rows.Add(row);
           return row;
       });

Однако в dtMoistureLimits нет строк для всех "ProductID" и "DelivererID" в dtProduct . В настоящее время мое решение возвращает только совпадающие строки.

Как улучшить решение, чтобы оно возвращало также те строки, в которых нет данных для "ProductID" и "DelivererID" в dtMoistureLimits ?

Ответы [ 2 ]

0 голосов
/ 05 июля 2018

Решение с использованием синтаксиса метода без необходимости упоминания всех столбцов

var result = table1.Rows.Cast<DataRow>()
   .Join(table2.Rows.Cast<DataRow>(),                      // join table1 and table2
      t1 => Convert.ToInt32(t1.Field<string>("ProductID")) // from every t1 get the productId
      t2 => t2.Field<int>("FuelId")                        // from every t2 get the fuelId,
      (t1, t2) => new                                  // when they match 
      {                                                // make a new object
           T1 = t1,                                    // containing the matching t1 and t2
           T2 = t2,
      }
0 голосов
/ 04 июля 2018
    var JoinedResult = (from t1 in table1.Rows.Cast<DataRow>()
               join t2 in table2.Rows.Cast<DataRow>() 
               on Convert.ToInt32(t1.Field<string>("ProductID")) equals t2.Field<int>("FuelId")
               select new { T1 = t1,
                            T2 = t2.column_name // all columns needed can be listed here
                          }).ToList();

EDIT: Чтобы преобразовать приведенный выше результат в DataTable, используйте следующий метод:

    DataTable dataTable = new DataTable();

    //Get all the properties
    PropertyInfo[] Props = JoinedResult.Select(y=>y.T1).First().GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
    foreach (PropertyInfo prop in Props)
    {
        //Defining type of data column gives proper data table 
        var type = (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) ? Nullable.GetUnderlyingType(prop.PropertyType) : prop.PropertyType);
        //Setting column names as Property names
        dataTable.Columns.Add(prop.Name, type);
    }

    dataTable.Columns.Add(t2_column_name, t2_column_type);

    foreach (var item in JoinedResult)
    {
       var values = new object[Props.Length];
       for (int i = 0; i < Props.Length; i++)
       {
            //inserting property values to datatable rows
            values[i] = Props[i].GetValue(item.T1, null);
       }
       values[Props.Length] = item.T2;
       dataTable.Rows.Add(values);
   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...