C# 使用字典在数据表上动态构建条件

C# 使用字典在数据表上动态构建条件,c#,linq,dictionary,datatable,C#,Linq,Dictionary,Datatable,目前我可以查询我的数据表(dtContacts),如下所示: 如果我在找一个人,他的姓是“约翰”,而姓是“史密斯”。我的结果将是 DataTable dt = dtContacts.AsEnumerable().Where(c => c.Field<string>("FirstName") == "John" && c.Field<string>("LastName") == "Smith").CopyToDataTable(); DataTabl

目前我可以查询我的
数据表
(dtContacts),如下所示:
如果我在找一个人,他的
姓是“约翰”,而
姓是“史密斯”。我的结果将是

DataTable dt = dtContacts.AsEnumerable().Where(c => c.Field<string>("FirstName") == "John" && c.Field<string>("LastName") == "Smith").CopyToDataTable();
DataTable dt=dtContacts.AsEnumerable()。其中(c=>c.Field(“FirstName”)==“John”和&c.Field(“LastName”)==“Smith”).CopyToDataTable();
但是这种静态查询对我没有帮助,因为我的条件可能比这稍微复杂一些。因此,我希望我的LINQ更具动态性,以便它能够适应以下场景

我将在
字典中保存我的条件,如下所示:

Dictionary<string, string> dicConditions = new Dictionary<string, string>();
dicConditions.Add("FirstName", "John");
dicConditions.Add("LastName", "Smith");
dicConditions.Add("IsCustomer", "Yes");
DataTable dt = dtContacts
    .AsEnumerable()
    .Where(c => 
        dicConditions.All(kv => c.Field<string>(kv.Key) == kv.Value)
    ).CopyToDataTable();
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);
Dictionary=newdictionary();
添加(“名字”、“约翰”);
添加(“姓氏”、“史密斯”);
添加(“是客户”、“是”);
请注意,我们可以向该词典添加任意多的条件。 让我们假设main
DataTable
dtContacts始终包含字典键中提到的列名,因此我们不需要每次都进行检查

在新版本中,我们希望我们的LINQ根据
DIC条件
进行操作,并返回
FirstName
为“John”、
LastName
为“Smith”和
IsCustomer
为“Yes”的所有值


这个新的动态LINQ查询应该是什么样子的?

您可以这样做:

Dictionary<string, string> dicConditions = new Dictionary<string, string>();
dicConditions.Add("FirstName", "John");
dicConditions.Add("LastName", "Smith");
dicConditions.Add("IsCustomer", "Yes");
DataTable dt = dtContacts
    .AsEnumerable()
    .Where(c => 
        dicConditions.All(kv => c.Field<string>(kv.Key) == kv.Value)
    ).CopyToDataTable();
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);
DataTable dt=dt触点
.可计算的()
.其中(c=>
所有条件(kv=>c.字段(kv.键)==kv.值)
).CopyToDataTable();

其思想是两次应用LINQ—一次应用于
dtContacts
,一次应用于
Where
子句中的
dicConditions

您可以使用以下方法从字典中构建上面显示的谓词:

Dictionary<string, string> dicConditions = new Dictionary<string, string>();
dicConditions.Add("FirstName", "John");
dicConditions.Add("LastName", "Smith");
dicConditions.Add("IsCustomer", "Yes");
DataTable dt = dtContacts
    .AsEnumerable()
    .Where(c => 
        dicConditions.All(kv => c.Field<string>(kv.Key) == kv.Value)
    ).CopyToDataTable();
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 result= dtContacts.Rows.OfType<DataRow>().Where(r=>dicConditions.All(d=>r[d.key]==d.Value));
var result=dtContacts.Rows.OfType()。其中(r=>dicconments.All(d=>r[d.key]==d.Value));
您可能需要正确转换字典的值以与datatable兼容…
使用正则表达式支持通配符…等