如何在Linq中循环遍历Datatable?

3

我正在尝试在Datatables上执行内部连接

我的代码如下

 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个表格,而我的表格数量是不固定的。
我能循环遍历这些表格并执行联接吗?
这是否是最好的方法?
请帮忙。

3
"我的表数量不固定":这是什么意思?请进一步解释您的应用程序以及您最终需要什么,因为感觉LINQ可能根本不是正确的答案。 - Mike Perrenoud
这是Entity Framework吗? - Eren Ersönmez
我想说的是,我有一些代码可以返回多个表。 - Rohit
听起来你想要在运行时创建这样的查询。我自己从未使用过它,但是动态 LINQ 听起来似乎符合您的要求。这里有很多例子... - Robbie Dee
1
@MichaelPerrenoud 想象一下 DataSet 或表格的集合。这在查询生成器类型的应用程序中比较常见,用户需要运行查询,但不希望他们编写可能会影响数据库的 SQL 代码。 - Robbie Dee
2个回答

2
以下方法使用 DataTable 列表来处理动态数量的数据表。该代码生成一个 List 类型的 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();
    });

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 }
   );

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

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

听起来很困难,我确定它确实是。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接