C# Linq Expression could not be Translated

别来无恙 提交于 2020-12-12 03:59:13

问题


I am trying to execute a linq query to get all employes that have some specific skills. search.skills is a list of strings with some skills and I want to retrieve all the user which have all those skills (And condition). In my where clause on employees, exp.Skills is ICollection and expSkill.SkillName is the skill name

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

I am getting the following error while trying to execute it. I am using entityframework core 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.

Can anyone tell me what I am doing wrong in my query? Thanks


回答1:


EF Core currently cannot translate LINQ operators other than simple Contains on memory collections like your search.Skills.

So you need to find an alternative to memoryCollection.All operator. What I use in such case is the "count matches" approach, which find all matching records and compares the counts of the distinct values.

e.g. replace

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

with

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


来源:https://stackoverflow.com/questions/60504903/c-sharp-linq-expression-could-not-be-translated

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!