【问题标题】:Build a linq query based on conditional values基于条件值构建 linq 查询
【发布时间】:2015-04-12 05:37:32
【问题描述】:

我有大量的记录,每个人都在一个国家/地区。

我可以使用以下实体框架检索澳大利亚的所有人:

var people = db.People.Where(x=>x.Country == "Australia")

我不确定如何根据一组布尔值检索位于 X 国或 Y 国的人。

即:

bool USA = true;
bool Australia = false;
bool UK = true;
bool China = false;

如何构建在这种情况下会给我的 linq 查询:

var people = db.People.Where(x=>x.Country == "USA" || x.Country == "UK")

谢谢

【问题讨论】:

  • PredicateBuilder 和一堆 if 语句就是你要找的。​​span>
  • 问题是有 10 个国家,所以有很多排列。 -) 希望有一种使用 Dict 或其他东西的奇特方式
  • 排列?看我的回答。不涉及排列。
  • 嗯,得到 [System.NotSupportedException] --- {"LINQ to Entities 不支持 LINQ 表达式节点类型 'Invoke'。"} 尝试使用 PredicateBuilder。有什么想法吗?
  • 一切都好,用stackoverflow.com/questions/22406952/…解决了

标签: c# linq


【解决方案1】:

你应该使用PredicateBuilder:

var predicate = PredicateBuilder.False<People>();

if (USA)
    predicate = predicate.Or(p => p.Country == "USA");
if (Australia)
    predicate = predicate.Or(p => p.Country == "Australia");

// ...

var people = dp.People.Where(predicate);

【讨论】:

  • 我认为 Joe 的代码的链接可能会在很长一段时间内保持有效。但是,实现非常短,恕我直言,这里可以完整引用,或者至少引用 Or() 方法部分。只要问题存在,这将确保此答案仍然有用。
【解决方案2】:

PredicateBuilder 是正确答案。作为替代方案,您可以执行以下操作:

var countries = new List<string>();

if(USA) countries.Add("USA");
if(Australia) countries.Add("Australia");
if(UK) countries.Add("UK");

// ...

var people = dp.People.Where(x => countries.Contains(x.Country));

这将被转换为WHERE IN SQL 子句

更新

正如 cmets 所指出的,在 Linq-To-Entities(或 Linq-To-SQL)场景中,这并不重要,但如果您打算将其用于 Linq-To-Objects,那就是出于性能原因,使用HashSet&lt;string&gt; 而不是List&lt;string&gt; 更明智

【讨论】:

  • @PeterDuniho 无论如何它都会被翻译成 SQL,所以集合的类型无关紧要 - Contains 将被翻译成 IN 子句并且从未实际调用过。
  • @PeterDuniho 你是对的,我会修改答案,我在考虑实体框架,而不是 Linq-To-Objects
【解决方案3】:

试试这个:

//You can add, remove or change filters
var tempDictionary = new Dictionary<string, bool>
{
    {"USA", true},
    {"Australia", false},
    {"UK", true},
    {"China", false},
};
//Get relevant filters
var tempFilter = tempDictionary
                 .Where(item => item.Value)
                 .Select(item => item.Key)
                 .ToArray();
var tempPeople = db
                 .People
                 .Where(x => tempFilter.Contains(x.Country));

【讨论】:

    猜你喜欢
    • 2011-09-29
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 2012-12-20
    • 1970-01-01
    • 2013-06-24
    • 2020-06-19
    相关资源
    最近更新 更多