EF Core 7 - 仅包含未删除的项目

问题描述 投票:0回答:1

在 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)?

谢谢!

c# linq lambda entity-framework-core expression
1个回答
0
投票

这个简单的扩展实现应该为

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);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.