问题
I have a class that inherits a base class to which another class has relationships.
Example:
- Base class: Animal
- Subclass 1: Dog
- Subclass 2: Cat
- Related one-to-many table: Vaccinations
- A dog can have multiple vaccinations. This is implemented as a List<Vaccination>.
- A cat can have multiple vaccinations.
- A vaccination record can only have one animal associated with it.
- A vaccination doesn't know if it's associated with a dog or a cat. (Dogs and cats use non-colliding GUIDs.)
There is no Animal table; Animal is an abstract class. But Vaccination knows only about Animal, not about Dog. (EF, however, knows about both.) I have my class libraries split such that Animal and Vaccination are in a core library and Dog is in another library that references the core library.
When using Entity Framework Code First, the Vaccinations table is getting the extra column: Dog_ID, as Dog class's List<Vaccination> explicit declaration is creating an inference. As such, this column maps the vaccination record to the dog. This would be fine, except for the fact that I want to share this extra column across multiple types of Animal. So for example rather than have a Dog_ID and a Cat_ID I'd like to have an Animal_ID that could join to either the Dog or the Cat.
As Animal is abstract and has no DB table, can I accomplish this with perhaps a fluent statement and/or property/attribute declarations?
回答1:
Your Vaccination
table will always have additional FK column for each vaccinated type of animals unless you create Animal
table and make relation to that table. EF cannot map and high level abstraction of relations - relations must follow same rules as if you create them directly in the database.
If only some animals can be vaccinated you can add another table to hierarchy and make relation with that new table (EF is not able to work with interfaces). You will need Table per Type mapping for that and it will make performance of your queries much worse in current EF version.
回答2:
Assuming all your animals will have vaccinations
public abstract class Animal
{
public string ID { get; set; }
public ICollection<Vaccination> Vaccinations { get; set; }
}
public class Vaccination
{
public string ID { get; set; }
public string AnimalID { get; set; }
public virtual Animal Animal { get; set; }
//other properties
}
Then you can inherit Cat
and Dog
and use Table per Type
mapping.
回答3:
So as I implemented what is currently marked as the answer (that I ultimately need to go ahead and create that Animal table) I ran into problems because, as I explained in my question, I have an isolated project declaring the "Dog", and for this and related issues I am directed here, here, and here.
来源:https://stackoverflow.com/questions/6579362/ef-code-first-abstract-relationship