【问题标题】:Entity Framework Generic Inheritance实体框架通用继承
【发布时间】:2015-01-28 06:07:53
【问题描述】:

我正在尝试分配从更通用的类继承的类的 DbSet。下面的示例演示了我想要实现的目标:

DbSet<Animal> dbSet;

switch (selectedAnimal)
{
    case "Dog":
        dbSet = _Context.Dog; // DbSet<Dog>
        break;
    case "Cat":
        dbSet = _Context.Cat; // DbSet<Cat>
        break;
    case "Pig":
        dbSet = _Context.Pig; // DbSet<Pig>
        break;
}

DogCatPig类是Animal的继承类,如下:

public class Dog : Animal { }

但是我得到一个编译时错误 Cannot implicitly convert type DbSet&lt;Dog&gt; to DbSet&lt;Animal&gt;

如何在不出错的情况下实现我的设计?

附:上面的代码只是为了说明我想要实现的目标,如果没有意义,请原谅我。

【问题讨论】:

标签: c# entity-framework generics inheritance


【解决方案1】:

您所指的称为协方差。在 C# 中,只有接口可以是协变的。所以IEnumerable&lt;Cat&gt;IEnumerable&lt;Animal&gt; 的子类型。声明DbSet&lt;Animal&gt; 然后将DbSet&lt;Cat&gt; 类型的变量放入其中的问题在于DbSet&lt;Animal&gt; 类型的变量具有允许例如添加Animal 实体的方法。 Animal 可能是 Dog。但是您输入的变量是DbSet&lt;Cat&gt;,并且不能包含Dog。这将违反强类型。

【讨论】:

  • 那么按照你的说法,如果我把Animal改成一个界面,它会起作用吗?即使将Animal 从类更改为接口,它似乎也不起作用。
  • 不,我是说如果DbSet 是一个接口(如果它以某种方式声明,请阅读关于协变和逆变的维基页面)。你试图做的事情无法完成。
【解决方案2】:

因为编译器无法将派生类转换为基类而不会丢失信息。 您根本无法将 Cat 的 DbSet 放入 Animal 的 DbSet 中,其中 Cat : Animal

但是你可以把 Animal 的 DbSet 放到 Cat 的 DbSet 中

试试这个:

var dbSet = GetDbSet(selectedObject) //selectedObject is Cat,Dog,Pig whatever

以及方法:

    private DbSet<T> GetDbSet<T>(T selectedAnimal) where T : Animal
    {
        return this.Set<T>(); //this == EF Context
    }

【讨论】:

  • 这不能回答我的问题。我正在尝试将派生类的 DbSet 设置为基类的 DbSet,根据@ChrisV,协方差。我不明白您的回答如何做到这一点,无论如何,谢谢!
猜你喜欢
  • 1970-01-01
  • 2011-05-19
  • 2010-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-08
相关资源
最近更新 更多