0

I'm trying to assign a DbSet of class that is inherited from a more generic class. The example below demonstrates what I'm trying to achieve:

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;
}

The Dog, Cat, Pig class is an inherited class of Animal, as follows:

public class Dog : Animal { }

But I am getting a compile-time error of Cannot implicitly convert type DbSet<Dog> to DbSet<Animal>

How can I implement my design without getting the error?

P.S. The code above is just to illustrate what I'm trying to achieve, so forgive me if it doesn't make sense.

2

2 Answers 2

1

What you're referring to is called covariance. In C# only interfaces can be covariant. So IEnumerable<Cat> is a subtype of IEnumerable<Animal>. The problem with declaring a DbSet<Animal> and then putting a variable of type DbSet<Cat> in it is that a variable of type DbSet<Animal> has methods that allow, for instance, adding an Animal entity. That Animal might be a Dog. But the variable you put in there was a DbSet<Cat> and that can't contain Dog. It would be a violation of strong typing.

Sign up to request clarification or add additional context in comments.

2 Comments

So according to what you are saying, will it work if I change Animal into an interface? It doesn't seem to work even after changing Animal from a class to interface.
No, I'm saying that it would work if DbSet were an interface (and if it were declared in a certain manner, read the wiki page on covariance and contravariance). What you're trying to do can't be done.
1

Because compiler cant cast derived classes to base class w/o information loss. You simply cant put DbSet of Cat into DbSet of Animal where Cat : Animal

But you CAN put DbSet of Animal into DbSet of Cat

Try this one:

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

And the method:

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

1 Comment

This doesn't answer my question. I'm trying to set a DbSet of derived class into a DbSet of base class, which according to @ChrisV, covariance. I don't see how your answer can do that, thanks anyway!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.