Исключение 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.

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

Вот мой выходной журнал: enter image description here

Ниже приведено сообщение об исключении: 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; }
}

Edit

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

enter image description here

   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);

Неважно, если его валюта и разблокировка, друзья и валюта, настройки и статистика. Любая комбинация include (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 как коллекцию, когда используется ссылка на одно поле.

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

Ответы

Ответ 1

Я получил эту проблему при отладке, в то время как мои коллеги не были. После долгих царапин мы обнаружили, что я был единственным, у которого флажок Debugging> General> Enable Just My Code снят.

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

Ответ 4

Просто хотел добавить мои 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" в поле редактирования справа
  • Нажмите OK и закройте окно

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

Приветствия.