假设我有这个初始代码:
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。我有没有的想法,如何做这样的事情。
答案 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。