AddRangeAsync () в Entity Framework Core не работает в общем методе - PullRequest
1 голос
/ 23 апреля 2019

Это работает:

await AddRangeAsync(myEntities);

Но это не работает:

await AddEntities(myEntities);

... когда я пытаюсь использовать эту функцию:

private async Task AddEntities<T>(IEnumerable<T> entities)
{
    await AddRangeAsync(entities);
}

Я получаю ошибку: "The entity type 'List<MyType>' was not found. Ensure that the entity type has been added to the model."

Это часть больших усилий по абстракции, которые я прилагаю. Почему я получаю эту ошибку и как ее устранить?

1 Ответ

2 голосов
/ 24 апреля 2019

Это еще один пример params object[] ловушки.

AddRangeAsync имеет две перегрузки:

(1)

Task AddRangeAsync(IEnumerable<object> entities, CancellationToken cancellationToken = default)

(2) * * 1 010

Task AddRangeAsync(params object[] entities)

Полагаю, вы хотите вызвать (1), но вопрос в том, какой из них здесь на самом деле называется:

private async Task AddEntities<T>(IEnumerable<T> entities)
{
    await AddRangeAsync(entities);
}

Ответ - это зависит!

Если T имеет ограничение class, он вызовет (1), в противном случае (2). Это связано с тем, что IEnumerable<T> является ковариантным только для ссылочных типов, поэтому его можно рассматривать как IEnumerable<object>, только если компилятор знает, что T является ссылочным типом, что достигается с помощью ограничения class.

Похоже, ваш класс не имеет такого ограничения, поэтому компилятор обрабатывает аргумент IEnumerable<T> как object (все может быть приведено к object) и вызывает (2), передавая массив object одного элемента с аргумент, то есть фактический вызов в этом случае

await AddRangeAsync(new object[] { entities });

, который должен демистифицировать сообщение об ошибке.

С учетом вышесказанного либо используйте ограничение where T : class, либо Cast метод расширения:

await AddRangeAsync(entities.Cast<object>());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...