在.NET Entity Framework Core中如何复用Where调用中的逻辑?
复用BaseEntity的LINQ过滤逻辑
要解决重复编写过滤代码的问题,你可以通过表达式树封装通用逻辑,EF Core能直接将表达式树转换为SQL,同时适配主查询和Include内的集合过滤场景。
1. 封装通用过滤表达式
创建静态类,定义返回Expression<Func<T, bool>>的方法,T限定为BaseEntity的子类:
public static class BaseEntityFilters { public static Expression<Func<T, bool>> IsActiveOrRecentlyDeleted<T>(DateTime cutoffDateTime) where T : BaseEntity { return entity => (entity.DeletedAt == null && entity.UpdatedAt > cutoffDateTime) || (entity.DeletedAt != null && entity.DeletedAt > cutoffDateTime); } }
2. 在查询中复用表达式
不管是主实体的过滤,还是Include内的子集合过滤,都可以直接调用这个方法:
var result = _context.Set<A>() // 子集合过滤:用AsQueryable()转换为可查询类型,传入表达式 .Include(a => a.Bs.AsQueryable().Where(BaseEntityFilters.IsActiveOrRecentlyDeleted<B>(dateTime))) // 主实体过滤:直接传入表达式 .Where(BaseEntityFilters.IsActiveOrRecentlyDeleted<A>(dateTime)) .ToList();
关键说明
- 表达式树是EF Core可解析的结构,主查询的
Where直接使用表达式,会被转换为SQL的WHERE条件。 - 子集合过滤时,通过
AsQueryable()将ICollection<B>转为IQueryable<B>,这样调用的是Queryable.Where(接受表达式参数),EF会把过滤条件整合到关联查询的SQL中,只加载符合条件的子实体,避免客户端过滤带来的性能问题。
内容的提问来源于stack exchange,提问作者stack_overflow_nickname
相关产品推荐
相关产品推荐

