linq查询中不同级别导航属性的相同where条件的通用表达式函数
Posted
技术标签:
【中文标题】linq查询中不同级别导航属性的相同where条件的通用表达式函数【英文标题】:Common expression function for same where condition at different level navigation properties in linq query 【发布时间】:2022-01-04 01:37:16 【问题描述】:假设我有一个这样的数据库实体结构
public class Parent
public virtual Child Child get; set;
public class Child
public string Property_1 get; set;
现在说我有两个这样的 linq 查询
var children = _context.Child.Where(c => c.Property_1 == "X").ToList();
var parents = _context.Parent.Where(p => p.Child.Property_1 == "X").ToList();
这两种情况下的 where 条件在一次意义上是完全相同的。
现在我可以将第一个条件放在一个单独的函数中,该函数将返回 expression
,然后我可以在想要选择具有此条件的子项时使用它。
但即使选择父级时的第二个条件也相同,但我仍然无法对 where 子句使用相同的表达式函数,因为它将接受 Child
类型的对象。
所以我的问题是,有没有可能将 where 条件放在一个单独的函数中,以便它可以与两个 linq 查询一起使用?
【问题讨论】:
这个question 很可能与您要查找的内容有关。 【参考方案1】:你可以使用LINQKit来完成这样的任务,它可以扩展可重用的方法。
public static class QueryExtensions
[Expandable(nameof(IsXValueImpl))]
public static bool IsXValue(this Child child)
throw new NotImplementedException();
private static Expression<Func<Cahild, bool>> IsXValueImpl()
return child => child.Property_1 == "X";
及用法:
var children = _context.Child.Where(c => c.IsXValue()).ToList();
var parents = _context.Parent.Where(p => p.Child.IsXValue()).ToList();
可以在选项构建期间激活 LINQKit:
builder
.UseSqlServer(connectionString)
.WithExpressionExpanding(); // enabling LINQKit extension
或者通过AsExpandable()
分机:
var children = _context.Child.AsExpandable().Where(c => c.IsXValue()).ToList();
var parents = _context.Parent.AsExpandable().Where(p => p.Child.IsXValue()).ToList();
【讨论】:
我不想使用外部库。不使用外部库就没有别的办法了吗? 仅在您重复此类功能的情况下。您必须扩展表达式并注入原始表达式树。 EF Core 本身在查询数据时过于笨拙,这就是为什么有很多扩展的原因。我知道至少三个做同样事情的第三方库。以上是关于linq查询中不同级别导航属性的相同where条件的通用表达式函数的主要内容,如果未能解决你的问题,请参考以下文章
实体框架Linq查询:如何在多个导航属性上从何处选择并从第三个导航属性中选择
Linq to Entities 中的动态 where 子句 (OR)