3

我正在尝试对我拥有的数据表执行内部联接

我的代码如下

 var Result = from row1 in t1
              join row2 in t2 on row1.ID equals row2.ID
              join row3 in t3 on row1.ID equals row3.ID
              select new { Emp.ID = row1.ID, Col1 = row2.col1, Col2 = row3.col2 

在此代码段中只有 3 个表而我的表数不固定

我可以遍历表并执行联接吗?

这会是最好的方法吗?

请帮忙

4

2 回答 2

2

以下方法使用DataTable列表来处理动态数量的数据表。该代码产生一个Listof IEnumerable<object>。此示例假设将添加到连接中每个其他数据表的最终项结构的列值位于相同的位置(在我们的示例中,我使用了row2[1],因此我占据了第二个位置)。

[编辑]我还添加了一个连接多个列/连接表的示例

    // create the collection
    List<DataTable> dts = new List<DataTable>();

    // add some test datatables
    for (int i = 0; i < 10; i++)
    {
        var dt = new DataTable();
        dt.TableName = i.ToString();
        dt.Columns.Add("ID");
        dt.Columns.Add("col" + i.ToString());
        dt.Columns.Add("otherCol" + i.ToString());
        dt.Rows.Add(1, "x1" + i.ToString(), DateTime.Now);
        dt.Rows.Add(2, "x2" + i.ToString(), DateTime.Now);
        dts.Add(dt);
    }

    // get the ID column position in the first table
    var idPosition = dts[0].Columns["ID"].Ordinal;

    // used for storing the results
    var results = new List<IEnumerable<object>>();

    // add the columns from the first table
    results = dts[0].AsEnumerable()
        .Select(j => j.ItemArray.AsEnumerable()).ToList();

    // join all tables
    dts.Skip(1).ToList().ForEach((list) =>
    {
        results = results
        .AsEnumerable()
        .Join(
            list.AsEnumerable(),
            x => x.Skip(idPosition).First(),
            x => x["ID"],
            // select the second column
            (row1, row2) => row1.Concat(new[] { row2[1] }))
            // replace the preceding line with 
            // the following one to select the second and the third column
            //(row1, row2) => row1.Concat(new[] { row2[1], row2[2] }))
        .ToList();
    });
于 2013-03-07T12:46:29.160 回答
1

一种方法(可能被标记为困难方法)是使用 Linq 的扩展方法构建连接组合。通过这种方式,您可以遍历您的集合(表),并添加任何必要的内容。

例如,这个:

from t1 in Table1
join t2 in Table2 on t1.ID equals t2.ID
join t3 in Table3 on t2.ID equals t3.ID
select new { t1, t2, t3 }

可以重写为(使用 LinqPad 很容易做到):

var query = Table1
   .Join (
      Table2, 
      t1 => t1.ID, 
      t2 => t2.ID, 
      (t1, t2) => new  { t1 = t1, t2 = t2 }
   )
   .Join (
      Table3, 
      temp0 => temp0.t2.ID, 
      t3 => t3.ID, 
      (temp0, t3) => new { t1 = temp0.t1, t2 = temp0.t2, t3 = t3 }
   )
;

这可以拆分,我想您可以在循环一组集合(您的 t1/t2/t3)时完成这项工作:

var query1 = Table1
   .Join (
      Table2, 
      t1 => t1.ID, 
      t2 => t2.ID, 
      (t1, t2) => new  { t1 = t1, t2 = t2 }
   );
var query2 = query1
   .Join (
      Table3, 
      temp0 => temp0.t2.ID, 
      t3 => t3.ID, 
      (temp0, t3) => new { t1 = temp0.t1, t2 = temp0.t2, t3 = t3 }
   );

不是一个完整的解决方案,但这是我试图解释的想法。

因此,您可以在循环一组集合时执行相同的操作,而不是“硬编码”query1、query2 等。

听起来很难,我相信它会是。

于 2013-03-07T12:45:28.680 回答