帮助使用LINQ查询DataTable

时间:2011-08-24 15:57:58

标签: c# linq

假设我有这个初始代码:

        DataTable table = new DataTable();
        table.Columns.Add("column1", typeof(int));
        table.Columns.Add("column2", typeof(int));
        table.Columns.Add("column3", typeof(string));
        table.Rows.Add(1, 0, "a");
        table.Rows.Add(2, 1, "b");
        table.Rows.Add(3, 1, "c");
        table.Rows.Add(4, 3, "d");
        table.Rows.Add(5, 3, "e");

如何使用LINQ执行这些操作?

一个。返回其列中的值也出现在column2中的DataRows。

到目前为止,我做到了这一点:

var x = (from t1 in table.AsEnumerable()
         select t1.Field<int>(0)).Intersect
        ((from t2 in table.AsEnumerable()
         select t2.Field<int>(1)).Distinct());

问题是,只返回column1的值,我使用了foreach。可能是因为select t1.Field<int>(0)部分,但我不知道如何返回DataRows本身。

湾返回column3的值,其column1中的值也出现在column2中。

与[a]几乎相同的问题。因为我已经使用过它,所以我只能返回column1行。我不知道如何返回除column1之外的DataRows和其他列(例如column3)。

我也试过这个:

var x1 = from t in table.AsEnumerable()
         select t;
var x2 = (from t in table.AsEnumerable()
          select t.Field<int>(1)).Distinct();

我希望在x1和x2上使用Intersect(),但我不知道如何。特别是因为x1有点像DataRow []而x2就像int []。

℃。将[a]中的答案用于另一个查询。

或者使用LINQ中的其他LINQ。我有没有的想法,如何做这样的事情。

3 个答案:

答案 0 :(得分:1)

我会为这三列创建一个新类。然后为新类创建一个Iqueryable或List,并将表行添加到其中。然后Linq表达式应该可以工作。

<强>类

public class myClass
{
    public int column1
    {
        get;
        set;
    }
    public int column2
    {
        get;
        set;
    }
    public stringcolumn3
    {
        get;
        set;
    }
}

<强> LINQ的

一个。返回其列中的值也出现在column2中的DataRows。

var x = (from l1 in myList
         where (from l2 in myList
                select l2.column2).contains(l1.column1)
         select l1);

湾返回column3的值,其column1中的值也出现在column2中。

var col3Values = (from l1 in myList
                  where l1.column2 = l1.column3
                  select l1.column3);

答案 1 :(得分:1)

方法:

a)    var result = (from t1 in table.AsEnumerable() 
                   join t2 in table.AsEnumerable() on t1.Field<int>(0) equals t2.Field<int>(1)  select t1).Distinct();

上面的查询返回IEnumerable<DataRow>。从此结果中,您可以为b)方案选择column3的值,如t2.Field<int>(2)

答案 2 :(得分:0)

在这里的人和其他一些网站的帮助下,我发现了如何真正做到[b]。

这将返回column3中的值,其中column1 中的值不会出现在column2中:

   from t in table.AsEnumerable()
       join t2 in table.AsEnumerable().Select(i => i.Field<int>(0)).Except(table.AsEnumerable().Select(j => j.Field<int>(1)))
       //the inner Select() returns column1 whose values in it also appears in column2
       //I can use either this or the first LINQ I made above
       //By the way, I said **does not** because I don't think I can use inner join on the opposite of [b]
       //unlike the Select() with lambda above; I can just change the Intersect() to Except() :)
       on t.Field<int>(0) equals t2
   where t.Field<int>(1) > 2          //If I need some other condition
   select t.Field<string>(2);

对于[c],我又做了一个表:

        DataTable tableA = new DataTable();
        tableA.Columns.Add("columnA", typeof(string));
        tableA.Columns.Add("columnB", typeof(string));
        tableA.Rows.Add("apple", "red");
        tableA.Rows.Add("banana", "yellow");
        tableA.Rows.Add("carrot", "orange");
        tableA.Rows.Add("dog", "commonly brown");      //ok, I can't think of a fruit/vegetable that starts with 'd' right now...
        tableA.Rows.Add("eggplant", "purple");

并将第一个表重命名为table1以避免/最小化混淆

    var x = from tA in tableA.AsEnumerable()
        from t1 in (
            from t1 in table1.AsEnumerable()
            join t2 in ((from t2_1 in table1.AsEnumerable()
                            select t2_1.Field<int>(0)).Except
                        ((from t2_2 in table1.AsEnumerable()
                            select t2_2.Field<int>(1))).Distinct())
            on t1.Field<int>(0) equals t2
            where t1.Field<int>(1) > 2        //extra condition
            select t1.Field<string>(2))
        where tA.Field<string>(0).StartsWith(t1)
        select tA;

返回tableA中的行,其columnA以返回的table1的column3开头,其column1值不出现在column2中,并且在column2中的值大于2。