这有效:
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."
这是我正在做的更大的抽象工作的一部分。为什么会出现此错误以及如何解决?
答案 0 :(得分:2)
这是params object[]
陷阱的另一个示例。
AddRangeAsync
有两个重载:
(1)
Task AddRangeAsync(IEnumerable<object> entities, CancellationToken cancellationToken = default)
(2)
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>());