如何创建一个通用扩展方法来包含 Entity Framework Core 嵌套集合属性,同时考虑到软删除属性?

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

我的所有实体都继承自

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
的方式工作,并且不会导致额外的数据库查询或内存处理。

c# linq entity-framework-core extension-methods
1个回答
0
投票

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