【问题标题】:C# Linq Expression could not be TranslatedC# Linq 表达式无法翻译
【发布时间】:2020-03-03 10:14:46
【问题描述】:

我正在尝试执行 linq 查询以获取所有具有某些特定技能的员工。 search.skills 是具有一些技能的字符串列表,我想检索所有具有所有这些技能(和条件)的用户。 在关于员工的 where 子句中,exp.Skills 是 ICollection,expSkill.SkillName 是技能名称

                .Where(
                emp => search.Skills.All(
                    searchSkill => emp.Experiences.Select(exp => exp.Skills).SelectMany(x => x).Select(expSkill => expSkill.SkillName).Contains(searchSkill)
                ))
            .ToListAsync();

我在尝试执行时收到以下错误。我正在使用实体框架核心 3

The LINQ expression 'DbSet<Employee>
.Where(e => __search_Skills_0
    .All(searchSkill => DbSet<Experience>
        .Where(e0 => EF.Property<Nullable<Guid>>(e, "Id") != null && EF.Property<Nullable<Guid>>(e, "Id") == EF.Property<Nullable<Guid>>(e0, "EmployeeId"))
        .SelectMany(
            source: e0 => DbSet<ExperienceSkill>
                .Where(e1 => EF.Property<Nullable<Guid>>(e0, "EmployeeId") != null && new AnonymousObject(new object[]
                { 
                    (object)EF.Property<Nullable<Guid>>(e0, "EmployeeId"), 
                    (object)EF.Property<string>(e0, "ProjectCode") 
                }) == new AnonymousObject(new object[]
                { 
                    (object)EF.Property<Nullable<Guid>>(e1, "ExperienceEmployeeId"), 
                    (object)EF.Property<string>(e1, "ExperienceProjectCode") 
                })), 
            collectionSelector: (e0, c) => new TransparentIdentifier<Experience, ExperienceSkill>(
                Outer = e0, 
                Inner = c
            ))
        .Select(ti => ti.Inner.SkillName)
        .Contains(searchSkill)))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

谁能告诉我我在查询中做错了什么?谢谢

【问题讨论】:

  • 错误提示:“要么以可翻译的形式重写查询,要么通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList( ) 或 ToListAsync()"。 IEnumerable 与 IQueryable,在 EF 中很难扭转你的想法。我将尝试在 SO 上找到一个参考问题,对此给出明确的解释
  • 我看到你的“.ToListAsync();”不包含在错误消息中,从缩进判断它适用于查询的外部。也许尝试直接在 where 子句上应用一个?
  • 我正在申请 .ToListAsync();紧跟在 where 子句之后
  • 可能与stackoverflow.com/questions/58690473/…stackoverflow.com/questions/58690473/…有关。我们可以看看类声明吗?
  • ID 是作为 GUID、int 还是 string 存储在数据库中的?

标签: c# entity-framework linq entity-framework-core .net-core-3.0


【解决方案1】:

EF Core 目前无法在诸如 search.Skills 之类的内存集合上转换简单的 Contains 以外的 LINQ 运算符。

因此您需要找到memoryCollection.All 运算符的替代方案。我在这种情况下使用的是“计数匹配”方法,它找到所有匹配的记录并比较不同值的计数。

例如替换

emp => search.Skills.All(
    searchSkill => emp.Experiences.Select(exp => exp.Skills).SelectMany(x => x).Select(expSkill => expSkill.SkillName).Contains(searchSkill)

emp => emp.Experiences
    .SelectMany(exp => exp.Skills, (exp, skill) => skill.SkillName)
    .Where(skillName => search.Skills.Contains(skillName))
    .Distinct().Count() == search.Skills.Distinct().Count()

【讨论】:

    猜你喜欢
    • 2021-12-28
    • 1970-01-01
    • 2022-12-03
    • 2021-11-27
    • 2022-10-20
    • 2020-09-29
    • 2021-07-01
    • 1970-01-01
    相关资源
    最近更新 更多