Мое присоединение .NetCore 3.1 вызывает исключение о NavigationExpandingExpressionVisitor, что это? - PullRequest
3 голосов
/ 28 февраля 2020

У меня есть проект .NetCore 3.1. Я знаю, что с EF Core 2 до 3 происходят серьезные изменения, но поиск решения этой проблемы приводит меня к неважным местам.

В .NetCore 2.2 работает следующее.

У меня есть список имен пользователей, сгенерированный из других запросов. Теперь я хочу найти эти имена пользователей в нашей базе данных персонала с целью возврата соответствующего адреса электронной почты для каждого имени пользователя. Человек может решить использовать адрес электронной почты компании или предоставить другой адрес. Если поле person.EmailAddress пустое, то мне нужен адрес пользователя с добавленным доменом компании.

private static List<string> GetEmailAddrsFromBp(PersonnelContext personnelContext, IEnumerable<string> userNames) {
    try {

        var personEmail = (
            from person in personnelContext.Persons
            join userName in userNames
                on person.userName.Trim().ToLower() equals userName.Trim().ToLower()
            where person.ActualEndDate == null
            select person.EmailAddress.Trim().Equals("")
                ? person.userName.Trim().ToLower() + "@myCompany.com"
                : person.EmailAddress.Trim().ToLower()
        ).Distinct().OrderBy(a => a).ToList();

        return personEmail;
    } catch (Exception e) {
        throw new Exception("GetEmailAddrsFromBp: " + e.Message);
    }
}

в 3.1 Я получаю исключение:

Processing of the LINQ expression 'DbSet<Persons>
    .Join(
        outer: __p_0, 
        inner: person => person.userName.Trim().ToLower(), 
        outerKeySelector: userName => userName.Trim().ToLower(), 
        innerKeySelector: (person, userName) => new { 
            person = person, 
            userName = userName
         })' by 'NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core. See https://go.microsoft.com/fwlink/?linkid=2101433 for more detailed information.

Я не понять эту ошибку. Переход на предлагаемый сайт Microsoft не поможет. Другой поиск в Google оказался бесполезным. Что здесь происходит? Как вы делаете "простые" соединения сейчас?

1 Ответ

3 голосов
/ 28 февраля 2020

Я не понимаю эту ошибку.

Сообщение об ошибке, конечно, не является удобным для пользователя. Единственная релевантная часть -

. Это может указывать на ошибку или ограничение в EF Core.

, которое можно смело читать как "This это либо ошибка, либо ограничение в EF Core. "

Что происходит? Как вы теперь делаете «простые» объединения?

Вы можете делать «простые» объединения, но не присоединяются к памяти коллекциям. На самом деле присоединения к коллекциям памяти никогда не поддерживались. Просто EF Core 1.x / 2.x использовал так называемую оценку клиента для вещей, которые он не может перевести. Но неявная оценка клиента была удалена в 3.0 , и теперь вы должны либо найти переводимую конструкцию, либо явно переключиться на оценку клиента через LINQ to Objects (или System.Linq.Async).

Поскольку переход к оценке клиента не является эффективным, особенно для объединений лучше найти / использовать переводимую конструкцию запроса. Если вы используете неэквивалентное или многоключевое соединение, у вас практически нет выбора. Но для равного соединения с одним ключом есть конструкция, которая поддерживается во всех версиях EF / EF Core, и это Enumerable.Contains, что переводится как SQL IN (val1, val2, ..., valN).

Так что решение для вас конкретное дело будет примерно так:

userNames = userNames.Select(userName => userName.Trim().ToLower()).Distinct();

var personEmail = (
    from person in personnelContext.Persons
    where userNames.Contains(person.userName.Trim().ToLower())
    // the rest of the query unchanged...
...