Исключение 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.
Кто-нибудь знает, что может быть причиной этих внутренних исключений и как я могу их устранить или смягчить?
Вот мой выходной журнал:
Ниже приведено сообщение об исключении:
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
Ключи для таблицы статистики аккаунта
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
в окне "Вывод", код вернулся к нормальной скорости, и я мог счастливо жить, уткнувшись головой в песок.
Ответ 2
У меня точно такая же проблема. Это ошибка, связанная с отладкой (см. https://github.com/aspnet/EntityFrameworkCore/issues/12548), которая будет исправлена только в версии 3.0.
Ответ 3
Ответ @Sean Malone сделал свое дело для меня.
Отметьте опцию "Включить только мой код" в Visual Studio, Инструменты меню => Параметры => Отладка => Общие
https://docs.microsoft.com/fr-fr/visualstudio/debugger/just-my-code?view=vs-2019
Ответ 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 и закройте окно
Та же проблема не будет беспокоить вас снова, но вы сможете поймать то же исключение из других мест. Я считаю это весьма полезным во время отладки.
Приветствия.