我是LINQ的新手,所以我确信我的逻辑中存在错误。
我有一个对象列表:
class Characteristic
{
public string Name { get; set; }
public string Value { get; set; }
public bool IsIncluded { get; set; }
}
使用列表中的每个对象,我想在LINQ中构建一个以DataTable
开头的查询,并根据对象值对其进行过滤,并生成DataTable
作为结果
我的代码到目前为止:
DataTable table = MyTable;
// Also tried: DataTable table = MyTable.Clone();
foreach (Characteristic c in characteristics)
{
if (c.IsIncluded)
{
var q = (from r in table.AsEnumerable()
where r.Field<string>(c.Name) == c.Value
select r);
table = rows.CopyToDataTable();
}
else
{
var q = (from r in table.AsEnumerable()
where r.Field<string>(c.Name) != c.Value
select r);
table = q.CopyToDataTable();
}
}
更新
我匆匆忙忙地犯了一个错误;我的DataTable
不是空的,我只是忘了把它绑定到DataGrid
。但是, Henk Holterman 指出我每次迭代都会覆盖我的结果集,这是一个逻辑错误。
到目前为止,Henk的代码似乎效果最好,但我需要做更多的测试。
Spinon的回答也有助于我清醒,但他的代码给了我一个错误。
我需要尝试更好地理解Timwi的代码,但在目前的形式中,它对我不起作用。
新代码
DataTable table = new DataTable();
foreach (Characteristic c in characteristics)
{
EnumerableRowCollection<DataRow> rows = null;
if (c.IsIncluded)
{
rows = (from r in MyTable.AsEnumerable()
where r.Field<string>(c.Name) == c.Value
select r);
}
else
{
rows = (from r in MyTable.AsEnumerable()
where r.Field<string>(c.Name) != c.Value
select r);
}
table.Merge(rows.CopyToDataTable());
}
dataGrid.DataContext = table;
答案 0 :(得分:3)
你发布的逻辑很糟糕;这是我尝试实现的认为的尝试。
DataTable table = MyTable.AsEnumerable()
.Where(r => characteristics.All(c => !c.IsIncluded ||
r.Field<string>(c.Name) == c.Value))
.CopyToDataTable();
如果您确实想要在帖子中使用逻辑,请将||
更改为^
,但这似乎毫无意义。
答案 1 :(得分:1)
你为每个特征覆盖table
变量,所以最后它只保存最后一轮的结果,而且显然是空的。
你可以做的是:
// untested
var t = q.CopyToDataTable();
table.Merge(t);
我怀疑你的查询应该使用MyTable作为源:
var q = (from r in MyTable.AsEnumerable() ...
但这并不完全清楚。
答案 2 :(得分:1)
如果您尝试将行插入表中,请尝试以这种方式调用CopyToDataTable方法:
q.CopyToDataTable(table, LoadOption.PreserveChanges);
这种方式不是重新分配表变量,而是可以使用要插入的新行更新它。
编辑:以下是我所谈论的一个例子:
DataTable table = new DataTable();
table.Columns.Add("Name", typeof(string));
table.Columns.Add("Value", typeof(string));