目前,我可以像这样查询我的DataTable
( dtContacts ):
如果我正在寻找一个FirstName
是" John"而LastName
是"史密斯"。我的结果将是
DataTable dt = dtContacts.AsEnumerable().Where(c => c.Field<string>("FirstName") == "John" && c.Field<string>("LastName") == "Smith").CopyToDataTable();
但是这样的静态查询对我没有帮助,因为我的条件可能比这稍微复杂一些。所以我希望我的LINQ更具动态性,因此它可以适应以下场景。
我将以Dictionary<string,string>
这样的方式保存我的病情:
Dictionary<string, string> dicConditions = new Dictionary<string, string>();
dicConditions.Add("FirstName", "John");
dicConditions.Add("LastName", "Smith");
dicConditions.Add("IsCustomer", "Yes");
请注意,我们可以为此词典添加任意数量的条件。
我们假设主DataTable
dtContacts 总是包含字典键中提到的列名,因此我们不需要每次都检查它。
在新版本中,我们希望我们的LINQ根据dicConditions
行事,并返回FirstName
为&#34; John&#34;,LastName
为&#的所有值34;史密斯&#34; IsCustomer
是&#34;是&#34;。
这个新的动态LINQ查询应该如何?
答案 0 :(得分:3)
你可以这样做:
DataTable dt = dtContacts
.AsEnumerable()
.Where(c =>
dicConditions.All(kv => c.Field<string>(kv.Key) == kv.Value)
).CopyToDataTable();
我们的想法是两次应用LINQ - 一次到dtContacts
,在dicConditions
子句中一次到Where
。
答案 1 :(得分:1)
您可以使用以下方法从字典构建上面显示的谓词:
using StringKvp = System.Collections.Generic.KeyValuePair<string, string>;
using DataRowPredicate = System.Func<System.Data.DataRow, bool>;
...
var pred = dicConditions.Aggregate<StringKvp, DataRowPredicate>(r => true,
(net, curr) => r => net(r) && r.Field<string>(curr.Key) == curr.Value);
然后,只需使用此谓词过滤您的集合:
var dt = dtContacts.AsEnumerable().Where(pred).CopyToDataTable();
答案 2 :(得分:0)
var result= dtContacts.Rows.OfType<DataRow>().Where(r=>dicConditions.All(d=>r[d.key]==d.Value));
您可能需要正确转换字典的值以与数据表兼容...
使用正则表达式来支持通配符......等等......