【发布时间】:2017-03-12 08:52:50
【问题描述】:
我需要多次检查相同的特定条件(where 子句):
return _ctx.Projects.Where(p => p.CompanyId == companyId &&
(p.Type == Enums.ProjectType.Open ||
p.Invites.Any(i => i.InviteeId == userId))).ToList()
'&&'后面的部分将导致用户无法检索受限项目。
我想将此检查抽象为一个函数。将来这些条件可能会发生变化,我不想替换所有 LINQ 查询。
我使用以下扩展方法做到了这一点:
public static IQueryable<Project> IsVisibleForResearcher(this IQueryable<Project> projects, string userId)
{
return projects.Where(p => p.Type == Enums.ProjectType.Open ||
p.Invites.Any(i => i.InviteeId == userId));
}
现在我可以将 LINQ 查询更改为:
return _ctx.Projects.Where(p => p.CompanyId == companyId)
.IsVisibleForResearcher(userId).ToList()
这会生成相同的 SQL 查询。现在,当我想在另一个具有项目的 DbSet 上使用此扩展方法时,我的问题就开始了。
假设一家公司有项目。而且我只想检索用户至少可以看到一个项目的公司。
return _ctx.Companies
.Where(c => c.Projects.Where(p =>
p.Type == Enums.ProjectType.Open ||
p.Invites.Any(i => i.InviteeId == userId))
.Any())
这里我也喜欢用扩展方法。
return _ctx.Companies
.Where(c => c.Projects.AsQueryable().IsVisibleForCompanyAccount(userId).Any())
这会引发以下异常:
“System.NotSupportedException”类型的异常发生在 Remotion.Linq.dll 但未在用户代码中处理
附加信息:无法解析表达式“c.Projects.AsQueryable()”:当前不支持“System.Linq.Queryable.AsQueryable”方法的这种重载。
比我创建了以下扩展方法:
public static IEnumerable<Project> IsVisibleForResearcher(this ICollection<Project> projects, string userId)
{
return projects.Where(p => p.Type == Enums.ProjectType.Open ||
p.Invites.Any(i => i.InviteeId == userId));
}
但这也不起作用。
有人有想法吗? 或者朝着正确的方向迈出一步。
顺便说一句,我在 .NET Core 上使用 Entity Framework Core
更新:
使用Expression<Func<>> 会导致同样的异常:
目前不支持“System.Linq.Queryable.AsQueryable”。
更新 2
感谢@ivan-stoev 提供解决方案。 我还有一个问题。我还想检索“可见”项目的数量。
我通过这样做修复了它:
var companies = _ctx.Companies
.WhereAny(c => c.Projects, Project.IsProjectVisibleForResearcher(userId))
.Select(c => new CompanyListDto
{
Id = c.Id,
Name = c.Name,
LogoId = c.LogoId,
ProjectCount = _ctx.Projects.Where(p => p.CompanyId == c.Id)
.Count(Project.IsProjectVisibleForResearcher(userId))
});
但我找不到只使用c.Projects 而不是ctx.Projects.Where(p => p.CompanyId == c.Id) 的方法
生成的 SQL 是正确的,但我想避免这种不必要的检查。
真诚地, 布莱希特
【问题讨论】:
标签: c# .net entity-framework linq entity-framework-core