如何在不同实体中复用相同的Where子句?
问题:EF Core中复用权限过滤的Where子句
业务场景
在我的应用中,已登录的管理员用户需根据权限查看「合作伙伴」,基础实现代码如下:
public async Task<IList<Partner>> GetPartners(IList<Permission> permissions, Admin admin) { bool all = permissions.Any(x => x.Key == "SeePartners" && x.Value == "All"); bool sameArea = permissions.Any(x => x.Key == "SeePartners" && x.Value == "SameArea"); var p = _dbContext.Partners.Where(x => all || (sameArea && x.AreaId == admin.AreaId)); return await p.AsNoTracking().ToListAsync(); }
每个合作伙伴关联不同项目,管理员查看项目关联的合作伙伴时,仍需遵循相同的权限规则,基础实现代码如下:
public async Task<IList<ProgramPartner>> GetProgramPartners(IList<Permission> permissions, Admin admin, Guid programId) { bool all = permissions.Any(x => x.Key == "SeePartners" && x.Value == "All"); bool sameArea = permissions.Any(x => x.Key == "SeePartners" && x.Value == "SameArea"); var p = _dbContext.ProgramPartners.Where(x => x.ProgramId == programId && (all || (sameArea && x.Partner.AreaId == admin.AreaId)) ); return await p.AsNoTracking().ToListAsync(); }
需求与尝试
由于实际权限逻辑比示例复杂得多,我希望复用权限过滤的Where子句,避免重复代码。
我尝试编写返回布尔值的过滤方法,但EF Core无法将自定义方法翻译为SQL,执行时报错:
public bool FilterPartners(Partner partner, IList<Permission> permissions, Admin admin) { bool all = permissions.Any(x => x.Key == "SeePartners" && x.Value == "All"); bool ownArea = permissions.Any(x => x.Key == "SeePartners" && x.Value == "OwnArea"); return all || (ownArea && partner.AreaId == admin.AreaId); } public async Task<IList<Partner>> GetPartners(IList<Permission> permissions, Admin admin) { var p = _dbContext.Partners.Where(x => FilterPartners(x, permissions, admin)); return await p.AsNoTracking().ToListAsync(); } public async Task<IList<ProgramPartner>> GetProgramPartners(IList<Permission> permissions, Admin admin, Guid programId) { var p = _dbContext.ProgramPartners.Where(x => x.ProgramId == programId) .Where(x => FilterPartners(x.Partner, permissions, admin)); return await p.AsNoTracking().ToListAsync(); }
我还尝试过传递IQueryable以及使用Expression函数,但都没成功。
提问
这种复用权限过滤Where子句的需求是否可行?如果可行,正确的实现方式是什么?
内容的提问来源于stack exchange,提问作者Mads
相关产品推荐
相关产品推荐

