【问题标题】:How to throuhly join two datatables using linq without column names如何使用没有列名的 linq 连接两个数据表
【发布时间】:2018-07-04 10:18:06
【问题描述】:

这可能在其他地方得到了回答,但我还没有找到可行的解决方案。

我有两个数据表,我想将它们合并到一个数据表中,其中包含来自这两个数据表的所有数据,或者至少来自第一个数据表和第二个数据表的一些列。

我不想列出第一个数据表中的所有列(总共 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;

但这仅给出了 table1 中的列。如何从 table2 中获取列到我的结果?最后,我需要将结果添加到数据集。

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

编辑:

我最终以这个作为解决方案。 这遵循此处给出的示例Create join with Select All (select *) in linq to datasets

 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 中,dtProduct 中并非所有 "ProductID""DelivererID" 的行.目前我的解决方案只返回匹配的行。

如何改进解决方案以在 dtMoistureLimits 中返回没有 "ProductID""DelivererID" 数据的行?

【问题讨论】:

  • 如果您不知道列名,您希望将来如何对它们进行任何计算?
  • @NetMage,生成的数据集被传递到报告环境。列名包含在数据集中。

标签: c# linq join datatable


【解决方案1】:

使用方法语法的解决方案,不必提及所有列

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,
      }

【讨论】:

【解决方案2】:
    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();

编辑: 要将上述结果转换为 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);
   }

【讨论】:

  • 这将返回所有必需的数据,但我不知道如何将结果集转换为数据表/数据集。结果数据的一行具有以下数据结构:{ t1 = {System.Data.DataRow}, column_name = 17.0000 }。因此,JoinedResult 的单行包含一个 DataRow 元素和一个标量值。如何以优雅的方式将其转换为数据表?
  • 不要选择t1作为一个整体,像t1.column等一样列出它的所有列。这样你会得到想要的结果
  • Ajay,列出 table1 中的所有列(总共 180 列)不是我想要做的。
  • @MarkkuRintala 列出了一种方法来做到这一点。
  • 在另一种情况下我需要您的解决方案,但在您将 linq 查询结果转换为数据表的示例中,我在 dataTable.Columns.Add(prop.Name, type);@@@ 987654326@具有值`{System.Reflection.PropertyInfo[11]} {System.String RowError} {System.Data.DataRowState RowState} {System.Data.DataTable Table} {System.Object Item [Int32]} {System.Object项目 [System.String]} ... ... {System.Object 项目 [System.Data.DataColumn, System.Data.DataRowVersion]} {System.Object[] ItemArray} {Boolean HasErrors}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-14
  • 1970-01-01
  • 2014-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-23
相关资源
最近更新 更多