jus*_*mer 5 entity-framework covariance
我有一个工厂函数来返回一个DbSet(Of IItemType).实际的返回类型将永远是一个实现IItemType,例如DbSet(Of CategoryType).
我认为在泛型中支持协方差,这种方法可以正常工作,但是当我尝试运行代码时出现异常:
无法转换'System.Data.Entity.DbSet
1[CategoryType]' to type 'System.Data.Entity.DbSet1 [IItemType]' 类型的对象.
DbSet<T>不能共变.首先,这是因为在C#中,类不能是共变体...只有接口.其次,因为DbSet<T>有共变体和反变体方法.
请看以下两个例子.
DbSet<CategoryType> set = context.Set<CategoryType>();
IQueryable<IItemType> query = set.Where(x => x.Foo == Bar);
Run Code Online (Sandbox Code Playgroud)
所以我们知道所有CategoryType的事实都是IItemType,所以我们知道这总是可行的.
但反过来尝试这个......
DbSet<CategoryType> set = context.Set<CategoryType>();
IItemType newItemType = new ProductType();
set.Add(newItemType); // Compiler error.
Run Code Online (Sandbox Code Playgroud)
不是全部IItemType都是CategoryType.因此,如果我们可以强制转换DbSet<CategoryType>,DbSet<IItemType>我们会在添加时遇到运行时错误...因为编译器知道这可能并不总是有效,所以它不会让你进行转换.
但是,有些接口DbSet<T>确实允许Co-Variance.例如,您可以尝试将其转换IQueryable<IItemType>为.
但是,听起来您正在尝试使用针对接口的查询来查询DbSet ...尝试以下操作
DbSet<CategoryType> set = context.Set<CategoryType>();
IQueryable<IItemType> cast = set.OfType<IITemType>(); //(or .Cast<>() works too)
IQueryable<IItemType> query = cast.Where(x => x ....);
Run Code Online (Sandbox Code Playgroud)