使用Dictionary

时间:2015-06-23 14:53:59

标签: c# linq dictionary datatable

目前,我可以像这样查询我的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查询应该如何?

3 个答案:

答案 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));

您可能需要正确转换字典的值以与数据表兼容...
使用正则表达式来支持通配符......等等......