如何在Entity Framework的where子句中链接多个替代条件

10

我试图将以下查询重写为单独的语句:

var sql = Repository.Products.AsQueryable();

sql = sql.Where(x => x.Name == "aaaaa" || x.Name == "bbbbb");

如果我这样做:

sql = sql.Where(x => x.Name == "aaaaa");
sql = sql.Where(x => x.Name == "bbbbb");

那么得到的查询结果就等于:

sql = sql.Where(x => x.Name == "aaaaa" && x.Name == "bbbbb");

有没有关于如何以正确的方式实现它的想法?


4
原来的做法有什么问题? - Dan Teesdale
请查看https://dev59.com/Q3I95IYBdhLWcg3w5iU4,看看它是否与您想要实现的相关,因为想要拆分条件必须有一个很好的理由。 - Pricey
2
我在搜索过滤器中使用它,这使得用户可以提供可变数量的条件以包含在查询中。因此,在开始时条件的数量是未知的。 - dodbrian
请参考@GuruStron的答案。Where谓词只以And方式组合。如果您想要一个Or,则必须进行复杂的表达式树展开。请使用PredicateBuilder - Simon Belanger
2个回答

13

正确的方式是...就是。我的意思是,你可以将其写成

sql.Where(x => x.Name == "aaaaa").Concat(sql.Where(x => x.Name == "bbbbb"));

但那样做会更慢、无序,而且看起来也更奇怪。我不知道你想要什么,因为你发布的方式正确的。

然而,根据你的评论,似乎你想动态构建表达式。如果是这样,那么你需要一个PredicateBuilder

var predicate = PredicateBuilder.False<YourType>();
var search = new[] {"aaaaa", "bbbbb"};
foreach (string y in search)
{
    string name = y;
    predicate = predicate.Or(x => x.Name == name);
}
sql = sql.Where(predicate);

PredicateBuilder 的代码在这里


谢谢,这正是我在寻找的。生成的 SQL 如下所示:SELECT [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name], FROM [dbo].[Products] AS [Extent1] WHERE [Extent1].[Name] IN (N'aaaaa',N'bbbbb') - dodbrian
@user2537328:你可以使用更直接的方式来编写这个特殊的SQL,而不需要PredicateBuilder:sql = sql.Where(x => search.Contains(x.Name))。如果你在不同属性上有一个OR条件,那么PredicateBuilder是很有用的。 - Slauma
@Slauma 这是(我猜)一个例子。 - It'sNotALie.
是的,我想是这样。我只是在上面的评论中提到了IN子句。当然,PredicateBuilder解决了更一般的条件。 - Slauma
@Slauma:有趣的观点要记在心里,但在我的情况下,我确实使用了不同的属性(问题中的示例非常简化),因此我认为使用谓词是迄今为止最好的决定。 - dodbrian
旧话题,但如果您正在使用EF Core,则默认情况下会失败 - 而传统/ .NET Framework EF将在客户端上执行此操作,而不是在服务器上执行此操作,这就是为什么在EF Core中默认禁用它的原因。 - majorpayne27

4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接