我需要檢查相同的特定條件(where
條款)多次:實體框架的擴展方法ICollection/IQueryable的
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的核心
UPDATE:
使用Expression<Func<>>
導致相同的異常:
「System.Linq.Queryable。 AsQueryable'目前不支持。
UPDATE 2
THX @伊凡-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的,但我想以避免這種不需要的檢查。
真誠, 布萊希特
完全有效!非常感謝您的回答!祝你今天愉快! 有點想研究解決方案,所以下次我需要它時,我可以自己生成這樣的東西。 – ErazerBrecht
還有一個小問題。我在原始問題中將其作爲「更新2」發佈。生成的SQL是正確的,但我不喜歡我必須這樣做的方式。不要覺得自己有義務檢查! – ErazerBrecht
檢查它沒有問題。問題在於解決方案非常有限(正如我在開始時提到的) - 僅適用於頂級查詢。一旦你需要另一種方法(嵌套'Where','Count'等),特別是在你的更新中的'Select'內部,你會發現你需要越來越多的助手。可能你真的必須看看用於投影的AutoMapper('ProjectTo')和/或用於表達式組合的LinqKit。 –