C# 在本地对查找公共项进行评估

C# 在本地对查找公共项进行评估,c#,entity-framework-core,entity-framework-core-2.2,C#,Entity Framework Core,Entity Framework Core 2.2,使用Entity Framework Core 2.2,我有以下疑问: IQueryable<User> users = _context.Users.AsNoTracking(); User user = await users .Include(x => x.UserSkills) .ThenInclude(x => x.Skill) .FirstOrDefaultAsync(x => x.Id == 1); var userSkills = u

使用Entity Framework Core 2.2,我有以下疑问:

IQueryable<User> users = _context.Users.AsNoTracking();

User user = await users
  .Include(x => x.UserSkills)
  .ThenInclude(x => x.Skill)
  .FirstOrDefaultAsync(x => x.Id == 1);

var userSkills = user.UserSkills.ToList();

IQueryable<Lesson> lessons = _context.Lessons.AsNoTracking();

var test = lessons
  .Where(x => x.IsEnabled)
  .Where(x => x.LessonSkills.All(y => userSkills.Any(z => y.SkillId == z.SkillId))) 
  .ToList();
如何更改查询以解决此问题

更新

我需要使用额外的选项(
y.SkillLevelId x.IsEnabled)扩展此查询
.Where(x=>x.LessonSkills.All(y=>userSkills.Any)(z=>
y、 SkillId==z.SkillId
&& 

y、 SkillLevelId
userSkills
是内存中的集合,根据我目前使用EF6和EF Core的经验,我可以说内存中集合的唯一可靠的可翻译构造是
可枚举。包含内存集合中基元类型的
方法

所以下面解决的问题就是这个问题

首先(应该在查询表达式树之外):

而不是

.Where(x => x.LessonSkills.All(y => userSkills.Any(z => y.SkillId == z.SkillId)))
使用等效项(但可翻译):

更新:如果您不能使用
包含
,在EF Core开始支持它之前,您可以选择(1)包(我个人没有测试过,但想法很有趣),(2)使用
表达式
类手动构建
或基于
的谓词(很难,适用于小内存集合)和(3)例如,将内存集合替换为real
IQueryable

var userSkills = users
    .Where(x => x.Id == 1)
    .SelectMany(x => x.UserSkills);

并使用原始查询。

这是否回答了您的问题?否。错误“无法翻译,将在本地进行评估”是每次无法将Linq查询转换为SQL时发出的一般错误。您发布的问题与我的查询不同。错误可能相同,但导致错误的原因不同。我使用的是
var userSkills=user.userSkills.ToList();
将userSkills作为内存集合作为解决此问题的原因…我也可以在查询中使用user.userSkills,但我也得到了一个例外。我知道您正在对
UserSkill
对象进行内存集合。这就是问题所在,因为使用它的查询构造不会转换为SQL。而只选择ID和using
包含
有效。建议的解决方案有什么问题,您尝试过吗?因为我在发布之前就尝试过,而且它对我有效(EF Core 2.2.6)。抱歉,由于缺少我提供的信息,您的答案有问题。如果您检查我刚才添加的更新,我还需要比较另一个属性:SkillLevel。因此包含将不起作用…我最初没有发布此内容,因为我想简化问题,不希望遗漏会影响答案。抱歉。@MiguelMoura我明白了。不幸的是,这是非常重要的细节,因为除Contains之外的任何内容都不能用于内存集合。
var userSkillIds = user.UserSkills.Select(x => x.SkillId);
.Where(x => x.LessonSkills.All(y => userSkills.Any(z => y.SkillId == z.SkillId)))
.Where(x => x.LessonSkills.All(y => userSkillIds.Contains(y.SkillId)))
var userSkills = users
    .Where(x => x.Id == 1)
    .SelectMany(x => x.UserSkills);