gpt4 book ai didi

c# - Entity Framework Core DbContext.RemoveRange 和类型约束

转载 作者:太空狗 更新时间:2023-10-30 00:37:15 27 4
gpt4 key购买 nike

这段代码抛出异常

System.InvalidOperationException: The entity type 'List<..>' was not found. Ensure that the entity type has been added to the model.

private static void Update<T>(DbContext context, ICollection<T> existing, ICollection<T> updated)  // where T: class
{
context.RemoveRange(existing);
updated.ToList().ForEach(existing.Add);
}

但是,如果您添加类型约束 where T: class,则不会抛出异常。为什么是这样?我的印象是 C# 类型约束不会像这样影响运行时行为。两个版本编译都很好。

最佳答案

这里不是运行时行为,而是编译时方法重载决议和协变:

context.RemoveRange(existing);

RemoveRange方法有两个重载:

RemoveRange(IEnumerable<object> entities)

RemoveRange(params object[] entities)

具有类约束允许 C# 编译器使用 IEnumerable<object> 选择重载- 因为 ICollection<T>IEnumerable<T> , 和 IEnumerable<T>供引用类型 T是协变的,因此是 IEnumerable<object> .

没有类约束,唯一可用的选项是带有 params object[] 的方法争论。这是 params object[] 的缺点/副作用/陷阱之一。构造 - 每个参数 arg类型不是 object[]被视为 object并隐式传递为 new object[] { arg } .

因此,在前一种情况下,实际调用是

context.RemoveRange((IEnumerable<object>)existing);

在后一种情况下是

context.RemoveRange(new object[] { existing });

换句话说,列表作为对象传递,这会导致运行时异常。

这同样适用于所有其他 Range DbContext 的方法类 - AddRange , UpdateRangeAttachRange .

关于c# - Entity Framework Core DbContext.RemoveRange 和类型约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54658422/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com