我的所有实体都继承自
BaseEntity
类,其中包含一个 IsDeleted
属性。现在,当包含嵌套集合时,我需要明确指定
Where(e => !e.IsDeleted)
在
Include
子句中:
_dbContext.Posts
.Include(p => p.Comments.Where(c => !c.IsDeleted))
如何创建可以像这样使用的
IncludeNotDeleted
扩展方法:
_dbContext.Posts.IncludeNotDeleted(p => p.Comments)
请注意,我希望此方法完全按照
Include
的方式工作,并且不会导致额外的数据库查询或内存处理。
我没有使用 EF Core 对此进行测试,因此可能存在一些类型问题(例如,我假设
Comments
是 ICollection<T>
)但这是我尝试将传递的 p => p.Comments
转换为 p => p.Comments.Where(c => !c.IsDeleted))
:
public static class IQueryableExt {
public static IQueryable<T> IncludeNotDeleted<T, TProp>(this IQueryable<T> q, Expression<Func<T, ICollection<TProp>>> pathExpr)
where T : class {
// (T p)
var pathParm = pathExpr.Parameters[0];
// p.{property}
var pathBodyExpr = pathExpr.Body;
// (TProp prop)
var filterParm = Expression.Parameter(typeof(TProp), "prop");
// !prop.IsDeleted
var filterBody = Expression.Not(Expression.Property(filterParm, "IsDeleted"));
// (TProp prop) => !prop.IsDeleted
var filteredPathExpr = Expression.Lambda<Func<TProp, bool>>(filterBody, filterParm);
// p.{property}.Where(prop => !prop.IsDeleted)
var newBody = Expression.Call(typeof(Enumerable), "Where", new[] { typeof(TProp) }, pathBodyExpr, filteredPathExpr);
// (T p) => p.{property}.Where(prop => !prop.IsDeleted)
var newPathExpr = Expression.Lambda<Func<T, IEnumerable<TProp>>>(newBody, pathParm);
return q.Include(newPathExpr);
}
}