结合DataTable和给定Dictionary的C#Linq动态where语句

本文关键字:C#Linq 动态 where 语句 Dictionary DataTable 结合 | 更新日期: 2023-09-27 18:24:28

我知道在c#linq中有关于动态where子句的帖子,但是,我对linq有点陌生,认为提出的解决方案与我的情况无关。

问题如下:我有一个Dictionary<string, List<string>>。字典中的每个值表示一组值。例如:对于给定的关键字"food",其值可以是{"apple"、"tomato"answers"soup"}。此外,我有一个DataTable,它的列是字典的键。

我的任务是构建一个linq,它的where子句是根据字典构建的。因此,在多个值之间,将出现"or"条件,在键的值之间,会出现"and"或"or"条件。

我不能把它硬编码,因为它必须根据字典中的关键字动态更改。

我真的不知道如何连接多个where子句,这些子句可能符合我的要求。

结合DataTable和给定Dictionary的C#Linq动态where语句

您可以使用.Any()、.All()和.Contains()来实现您想要的内容,而不是连接linq表达式。

var filters = new Dictionary<string, List<string>> { {"Food",  new List<string> { "apple", "tomato", "soup"} },
                                                     {"Drink", new List<string> { "tea"                    }}};
var table = new System.Data.DataTable();
table.Columns.Add("Food");table.Columns.Add("Drink");
table.Rows.Add("apple" , "water");
table.Rows.Add("tomato", "tea");
table.Rows.Add("cake"  , "water");
table.Rows.Add("cake"  , "tea");
//And: Retrieves only tomato, tea
var andLinq = table.Rows.Cast<System.Data.DataRow>().Where(row => filters.All(filter => filter.Value.Contains(row[filter.Key])));
//Or: Retrieves all except cake, water
var orLinq = table.Rows.Cast<System.Data.DataRow>().Where(row => filters.Any(filter => filter.Value.Contains(row[filter.Key])));

Contains等效于等于val1或等于val2。

我更新了答案。这是我能从你的问题中得出的最准确的答案。
Dictionary<string, List<string>> filters = GetFilters();
var filteredSource = GetSource();            
bool useAndOperator = GetUseAndOperator();
foreach (var filter in filters.Values)
{
    Func<myDataRow, bool> predecate = useAndOperator ? s => filter.All(f => f == s["key1"])
                                                     : s => filter.Any(f => f == s["key1"]);
    filteredSource = filteredSource.Where(predecate);
}

此外,这段代码没有多大意义,但它展示了原理,而不是完整的解决方案,您应该根据需要进行相应的更新。