Проблема с запросом к базе данных, созданным EF - PullRequest
0 голосов
/ 22 марта 2020

Я хочу загрузить отфильтрованные данные из базы данных.

Здесь он фильтрует данные

return predicate
                .And(true, () => company => !String.IsNullOrEmpty(searchCriteria.Keyword) ? searchCriteria.Keyword.Contains(company.Name) : true)
                .Or(true, () => company => !String.IsNullOrEmpty(searchCriteria.Keyword) ? company.Employees.Any(x => x.FirstName == searchCriteria.Keyword) : true)
                .Or(true, () => company => !String.IsNullOrEmpty(searchCriteria.Keyword) ? company.Employees.Any(x => x.LastName == searchCriteria.Keyword) : true)
                .And(true, () => company => searchCriteria.EmployeeDateOfBirthFrom != null ? company.Employees.Any(x => x.DateOfBirth >= searchCriteria.EmployeeDateOfBirthFrom) : true)
                .And(true, () => company => searchCriteria.EmployeeDateOfBirthTo != null ? company.Employees.Any(x => x.DateOfBirth <= searchCriteria.EmployeeDateOfBirthTo) : true)
                .And(true, () => company => searchCriteria.EmployeeJobTitles != null ? company.Employees.Any(x=> searchCriteria.EmployeeJobTitles.Any(s=> s == x.JobTitle.ToString())) : true);

, а здесь я загружаю данные из базы данных:

 return await dbContext.Companies.Include(x => x.Employees).Where(predicate).ToListAsync();

Почему у меня возникла эта проблема и можно ли ее исправить?

System.InvalidOperationException: The LINQ expression 'DbSet<Employee>
    .Where(e => EF.Property<Nullable<long>>((EntityShaperExpression: 
        EntityType: Company
        ValueBufferExpression: 
            (ProjectionBindingExpression: EmptyProjectionMember)
        IsNullable: False
    ), "Id") != null && EF.Property<Nullable<long>>((EntityShaperExpression: 
        EntityType: Company
        ValueBufferExpression: 
            (ProjectionBindingExpression: EmptyProjectionMember)
        IsNullable: False
    ), "Id") == EF.Property<Nullable<long>>(e, "CompanyId"))
    .Any(e => __searchCriteria_EmployeeJobTitles_0
        .Contains(e.ToString()))' 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.
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.<VisitMethodCall>g__CheckTranslated|8_0(ShapedQueryExpression translated, <>c__DisplayClass8_0& )

Ответы [ 3 ]

0 голосов
/ 22 марта 2020

Я изменил его на:

.And(true, () => company => searchCriteria.EmployeeJobTitles != null ? company.Employees.Any(x=> searchCriteria.EmployeeJobTitles.Any(s=> (JobTitle)Enum.Parse(typeOf(JobTitle), s) == x.JobTitle)) : true);

все равно не работает

0 голосов
/ 22 марта 2020

EF Core не может перевести следующее выражение:

company.Employees.Any(x => searchCriteria.EmployeeJobTitles
    .Any(s => s == x.JobTitle.ToString()))

С этим связаны две проблемы.

Во-первых, searchCriteria.EmployeeJobTitles, похоже, находится в памяти и является единственным на данный момент. переводимый оператор для коллекций в памяти - Contains.

, поэтому его следует изменить на

company.Employees.Any(x => searchCriteria.EmployeeJobTitles
    .Contains(x.JobTitle.ToString()))

Но в соответствии с сообщением об исключении вы уже это сделали. Что приводит нас ко второй проблеме: x.JobTitle тип свойства выглядит как enum, а ToString() для перечислений не может быть переведен.

Таким образом, вы должны выполнить enum filter наоборот - конвертировать searchCriteria.EmployeeJobTitles из IEnumerable<string> в IEnumerable<JobTitle> и использовать Contains(x.JobTitle), избегая x.JobTitle.ToString():

company.Employees.Any(x => searchCriteria.EmployeeJobTitles
    .Select(t => Enum.Parse<JobTitle>(t))
    .Contains(x.JobTitle))
0 голосов
/ 22 марта 2020

Измените x.JobTitle.ToString() на x.JobTitle при создании предиката. ToString() не поддерживается на стороне базы данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...