在 EF Core 7 中,我能够过滤包含的集合,例如
var users = _context.Users.Include(x => x.Roles.Where(y => y.IsDeleted == false)).ToList();
我想进行扩展,将其简化为:
var users = _context.Users.Include(x => x.Roles, true).ToList();
其中 true 表示没有删除。
所以,我需要合并两个表达式,就我而言
Expression<Func<IDbEntityDelete, bool>> expression1 = x => !x.IsDeleted;
Expression<Func<User,ICollection<Role>>> expression2 = x => x.Roles;
第一个是常量表达式,第二个是在我的扩展中作为参数的表达式。
public static IIncludableQueryable<TEntity, TCollection> Include<TEntity, TCollection>(this IQueryable<TEntity> query, Expression<Func<TEntity, TCollection>> navigationExpression, bool withoutDeleted) where TEntity : class, IDbEntityDelete
{
}
你能帮我将 navigationExpression 与 expression1 结合起来吗?
那么结果 lambda 正是 x => x.Roles.Where(y => y.IsDeleted == false)?
谢谢!
这个简单的扩展实现应该为
Include
添加软删除过滤器:
public static class IncludeExtensions
{
public static IIncludableQueryable<TEntity, IEnumerable<TItem>> Include<TEntity, TItem>(
this IQueryable<TEntity> query,
Expression<Func<TEntity, IEnumerable<TItem>>> navigationExpression,
bool withoutDeleted
)
where TEntity : class
where TItem : class, IDbEntityDelete
{
if (!withoutDeleted)
{
return query.Include(navigationExpression);
}
// let the compiler to generate filter stuff.
Expression<Func<IEnumerable<TItem>, IEnumerable<TItem>>> filterTemplate = q => q.Where(e => !e.IsDeleted);
// replacing template parameter with navigationExpression
var filterBody = ReplacingExpressionVisitor.Replace(filterTemplate.Parameters[0], navigationExpression.Body, filterTemplate.Body);
var filterLambda = Expression.Lambda<Func<TEntity, IEnumerable<TItem>>>(filterBody, navigationExpression.Parameters);
return query.Include(filterLambda);
}
}