开发者

EF Code First abstract relationship?

开发者 https://www.devze.com 2023-03-18 12:53 出处:网络
I have a class that inherits a base class to which another class has relationships. Example: Base class: Animal

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 n开发者_如何学Co 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?


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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消