Исключение System.Linq.Expressions при использовании FirstOrDefault в .Net Core 2.1

Я получаю около 300+ исключений, которые засылаются спамом в выводе моего сервера с пометкой:

Exception thrown: 'System.ArgumentException' in System.Linq.Expressions.dll

Я использую следующий запрос:

Account account = _accountContext.Account.
     Include(i => i.Currency).
     Include(i => i.Unlocks).
     Include(i => i.Settings).
     Include(i => i.Friends).
     FirstOrDefault(a => a.FacebookUserID == facebookUserID);

В конце концов исключения перестают генерироваться, в окне вывода отображается большой запрос, и все продолжается как обычно.

Если я изменю запрос на следующий, я не испытаю исключения:

IQueryable<Account> account = _accountContext.Account.
     Include(i => i.Currency).
     Include(i => i.Unlocks).
     Include(i => i.Settings).
     Include(i => i.Friends).
     Where(a => a.FacebookUserID == facebookUserID);

Однако, если я вызываю что-нибудь вроде First, FirstOrDefault, Single и т. д. В переменной IQueryable<Account>, исключения запускаются снова, а затем останавливаются через ~ 300.

Эти исключения задерживают вход в систему более чем на 30 секунд. Продолжительность исключений увеличивается с увеличением количества данных, возвращаемых из базы данных.

Я использую объект Account, передавая его серверу для выполнения различных задач обслуживания, а затем в конечном итоге отправляю объект на стороне клиента, где он десериализуется в клиентскую версию класса Account.

Кто-нибудь знает, что может вызывать эти внутренние исключения и как я могу их устранить или смягчить?

Вот мой выходной журнал: Исключение System.Linq.Expressions при использовании FirstOrDefault в .Net Core 2.1

Ниже приведено сообщение об исключении: AccountStatistics не указан в приведенном выше запросе, потому что его около 20, и я сократил список для краткости.

Field 'Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor+TransparentIdentifier`2[Project.Models.Account,System.Collections.Generic.IEnumerable`1[Project.Models.AccountStatistics]].Inner' is not defined for type 'Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor+TransparentIdentifier`2[Project.Models.Account,Project.Models.AccountStatistics]'

Нет никакого внутреннего исключения. Я дважды проверил свою базу данных, и у меня есть запись для пользователя, и все его поля заполнены действительными данными.

Класс учетной записи (отредактировано для краткости)

public class Account
    {
        [Key]
        public int ID { get; set; }
        public DateTime CreationDate { get; set; }

        public AccountCurrency Currency { get; set; }
        public AccountProgression Progression { get; set; }
        public AccountSettings Settings { get; set; }
        public AccountStatistics Statistics { get; set; }

        public ICollection<AccountFriendEntry> Friends { get; set; }
        public ICollection<AccountUnlockedGameEntry> Unlocks{ get; set; }
    }

Класс статистики аккаунта

public class AccountStatistics
{
    [Key]
    public int AccountID { get; set; }
    public int LoginCount { get; set; }
    public DateTime LastLoginTime { get; set; }
    public DateTime LastActivityTime { get; set; }
}

Редактировать

Ключи для таблицы статистики аккаунта

Исключение System.Linq.Expressions при использовании FirstOrDefault в .Net Core 2.1

   migrationBuilder.CreateTable(
            name: "AccountStatistics",
            columns: table => new
            {
                AccountID = table.Column<int>(nullable: false),
                LoginCount = table.Column<int>(nullable: false),
                LastLoginTime = table.Column<DateTime>(nullable: false),
                CreationDate = table.Column<DateTime>(nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_AccountStatistics", x => x.AccountID);
                table.ForeignKey(
                    name: "FK_AccountStatistics_Accounts_AccountID",
                    column: x => x.AccountID,
                    principalTable: "Accounts",
                    principalColumn: "ID",
                    onDelete: ReferentialAction.Cascade);
            });

Изменить 9001

После некоторого тестирования я понял, что исключение возникает только при включении в цепочку.

Это вызовет исключение:

Account account = _accountContext.Account.
     Include(i => i.Currency).
     Include(i => i.Unlocks).
     Include(i => i.Settings).
     Include(i => i.Friends).
     FirstOrDefault(a => a.FacebookUserID == facebookUserID);

Это НЕ вызовет исключения:

Account account = _accountContext.Account.
     Include(i => i.Currency).
     FirstOrDefault(a => a.FacebookUserID == facebookUserID);

Неважно, валюта у него и анлок, друзья и валюта, настройки и статистика. Любая комбинация включает (2 или более) вызывает исключение.

Изменить 9002

Вот мои результаты следующего запроса:

var acct = _accountContext.Account
     .Where(a => a.FacebookUserID == facebookUserID)
     .Select(x => new { Account = x, x.Currency, x.Settings }).ToList();

Исключение:

System.ArgumentException: 'Field 'Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor+TransparentIdentifier`2[Project.Models.Account,System.Collections.Generic.IEnumerable`1[Project.Models.AccountSettings]].Inner' is not defined for type 'Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor+TransparentIdentifier`2[Project.Models.Account,Project.Models.AccountSettings]''

Мне кажется, что здесь AccountSettings рассматривается как коллекция, когда это ссылка на одно поле.

Редактировать финал: Я так и не нашел решения этой проблемы. Я воссоздал все таблицы и тому подобное в другой среде, и все работает нормально. Не очень идеальное решение для удаления всех таблиц, классов и миграций, но это единственное, что устранило проблему.

Часто бывает полезно при отладке исключений, если вы предоставляете подробную трассировку стека для исключения.

StriplingWarrior 28.08.2018 23:00

Вы пытались удалить эти элементы из выражения? Возможно, проблема связана с отношениями между сущностями. Если снимать по одному, возможно, удастся изолировать проблемный объект

mnieto 28.08.2018 23:03

@StriplingWarrior Нет трассировки стека исключения. Журнал вывода просто спамит эту строку исключения выше примерно 300 раз. Весь процесс окружен попыткой / уловом, но никогда не бросает. Я предполагаю, что это как-то связано с внутренним устройством этой .dll

steve 28.08.2018 23:04

@mnieto Я попробовал руководство .Where.Select с выбранными несколькими указанными столбцами, но в тот момент, когда я преобразовал это в объект и т. д. Это все еще происходит.

steve 28.08.2018 23:05

В VS во время отладки, если вы перейдете в Debug -> Windows -> Exception Settings, вы можете сказать VS немедленно сломать ArgumentException. Затем вы можете вызвать ошибки и отладить свой код. Отладчик, вероятно, остановится где-нибудь в непользовательском коде, поэтому потребуется проверка стека вызовов.

user47589 28.08.2018 23:07

Возможно, EF генерирует одно исключение для каждой строки, которая пыталась материализоваться. Измените отношения сущностей и любые возможные преобразования

mnieto 28.08.2018 23:12

Неплохо подмечено. Where не материализует ваши сущности, как и все методы, которые вызывают у вас проблемы. Вы можете рассмотреть возможность сопоставления ваших сущностей с базой данных. Что-то может быть неправильно нанесено на карту.

user47589 28.08.2018 23:13

Если бы мне пришлось запустить IQueryable версию этого, а затем проверить результат в VS, он правильно вернет все данные в окне intellisense, но фактическое преобразование вызывает исключения.

steve 28.08.2018 23:20

Можете ли вы опубликовать определение / сопоставление для класса AccountStatistics? Основываясь на деталях исключения, похоже, что у EF возникают проблемы с отображением отношения к этому классу. Я предполагаю, что у него должен быть идентификатор учетной записи FK для обратной ссылки на учетную запись.

Steve Py 29.08.2018 00:00

@StevePy Кажется, я добавил то, что вы искали. Если нет, дайте мне знать. Кажется, у него есть правильная ссылка FK на таблицу счетов.

steve 29.08.2018 01:00

Хм, ничего особенного. Это 1 к 1 на одном ПК. Есть ли у вас явные сопоставления для этих отношений? С AccountSettings это тоже использует AccountID в качестве PK? Что произойдет, если вы временно удалите сопоставление AccountStatistics из учетной записи? [NotMapped]

Steve Py 29.08.2018 02:20

@StevePy AccountSettings выглядит точно так же, как AccountStatistics. Вчера вечером я провел еще несколько тестов, и кажется, что исключение возникает только тогда, когда я делаю несколько включений. Если у меня есть только один включенный оператор, я не получу исключения. В тот момент, когда я добавляю второе включение - похоже, комбинация не имеет значения - я получаю то же исключение.

steve 29.08.2018 15:54

Это кажется очень странным. Попробуйте .Select(x => new { Account = x, x.Currency, x.Unlocks, x.Settings, x.Friends, x.Settings, x.Statistics }).ToList() после вашего .Where() без каких-либо инструкций .Include(). Мне было бы любопытно, вернет ли это данные без исключения, или это может пролить свет на проблему с сопоставлением, которая вызывает отключение .Include().

Steve Py 30.08.2018 00:45

@StevePy Разместил мои результаты в редакции 9002. Я попробовал этот оператор только с x.Currency, и он прошел, однако добавлял любое количество дополнительных x.TableNames, и исключения возвращались. Когда я не делаю ToList() и просто проверяю результаты внутри intellisense, это занимает некоторое время, а затем показывает мне правильные результаты. Не уверен, будет ли исключение выброшено в представлении результатов intellisense.

steve 30.08.2018 15:26

Похоже, это может быть ошибка или «особенность» EF Core, или что-то спрятанное где-то в сопоставлениях. Учитывая этот набор сущностей и сопоставлений, можете ли вы извлечь их в новый проект и попробовать его с EF 6.2? Если он работает с EF 6 для тех же таблиц / сопоставлений, это сузит его до Core и, возможно, чего-то, что можно поднять. Если это не работает с 6.2, вы можете получить другое исключение, которое может пролить дополнительный свет.

Steve Py 31.08.2018 01:10

показать конфигурацию моделей AccountSetting и Account

Moho 20.09.2018 16:34

Разве нет каких-либо декораторов, которые вы должны добавить к свойствам своей модели с ограничениями внешнего ключа? Я не на 100% уверен, необходимы они или нет, но, возможно, это касается реализации IQueryable.

Nicholi 03.10.2018 06:46

Та же проблема после обновления до vs2019, однако проблема возникла через несколько дней. Включение только моего кода было отличным трюком

sofsntp 16.09.2019 18:33
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
12
18
3 514
4

Ответы 4

У меня возникла эта проблема при отладке, а у моих коллег - нет. После долгих царапин в голове мы обнаружили, что я единственный, у кого отключен параметр Отладка> Общие> Включить только мой код.

Если поставить галочку, чтобы скрыть тысячи ошибок Exception thrown: 'System.ArgumentException' in System.Linq.Expressions.dll в окне вывода, код вернулся к нормальной скорости, и я мог спокойно жить, зарывшись головой в песок.

Была такая же ситуация со мной. Только что Enabled Just My code работал.

Wit Wikky 01.11.2018 14:25

Будьте осторожны при включении этого параметра, для веб-разработчиков это означает, что ваши точки останова на страницах Razor и т. д. Больше не будут затронуты ... Сообщения появляются только тогда, когда вы находитесь в режиме Debug, когда вы создаете свое приложение в режиме Release, операторы System.Diagnostics.Debug ( из библиотеки System.Linq.Expressions.dll) даже не включены в окончательный код, так что это не должно влиять на производительность. Правильный ответ, но убедитесь, что вы знаете, что делаете.

Alexander Derck 27.12.2018 11:57

У меня такая же проблема даже для сборок Release

pantonis 18.02.2020 13:46

Я предпочитаю просто снимать флажок "Прерывание при возникновении этого типа исключения"

waleed 22.03.2020 13:14

У меня точно такая же проблема. Это ошибка, связанная с отладкой (см. https://github.com/aspnet/EntityFrameworkCore/issues/12548), и будет исправлена ​​только в версии 3.0.

Ответ @Sean Malone помог мне. Установите флажок «Включить только мой код» в Visual Studio, Инструменты меню => Параметры => Отладка => Общие

https://docs.microsoft.com/fr-fr/visualstudio/debugger/just-my-code?view=vs-2019

Просто хотел добавить сюда свои 2 цента.

Похоже, нам придется жить с этим до версии 3.0, но отключение всех исключений из другого кода - не лучшая идея. Вы можете пропустить что-то важное во время отладки.

Я использую .NET Core 2.2.7, но время от времени это все равно возникает.

Используя Visual Studio 2019 (я также предполагаю, что 2017 год) вы можете отключить это исключение только для System.Linq.Expressions.

Это можно сделать следующим образом:

  • Откройте окно настроек исключения. Отладка -> Windows -> Настройки исключений (Ctrl + Alt + E)
  • В правом верхнем углу окна есть поле поиска, введите в нем "System.ArgumentException".
  • Вы увидите исключение, перечисленное в окне, щелкните его правой кнопкой мыши и выберите в меню «Изменить условия».
  • Условия редактирования позволяют установить условия, при которых отладчик прерывается при возникновении исключения.
  • Слева направо выберите "Имя модуля", выберите "Не равно" и введите "System.Linq.Expressions.dll" в поле редактирования справа.
  • Нажмите ОК и закройте окно.

Та же проблема больше не будет вас беспокоить, но вы сможете поймать то же исключение из других мест. Я считаю это весьма полезным во время отладки.

Ваше здоровье.

Другие вопросы по теме