Search code examples
entity-frameworkdictionarycode-first

Entity framework code first map entities to different tables


I have classes something like below. I would like to reuse classes and persist them in different tables by using entity framework code first.

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsAvailable { get; set; }
    public List<Part> Parts { get; set; }
    public List<Promotion> Promotions { get; set; }
}

public class Field
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
}

public class Part
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Field> Details { get; set; }
}

public class Promotion
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Field> Details { get; set; }
}

I want to map my entities such a way that I would get database tables generated like below.

Products: Id, Name, IsAvailable

ProductParts: Id, Name, ProductId

ProductPartDetails: Id, Name, Value, ProductPartId

ProductPromotions: Id, Name, ProductId

ProductPromotionDetails: Id, Name, Value, ProductPromotionId

What I am actually interested in here is I want the Field class reused and gets stored in different tables ProductPartDetails and ProductPromotionDetails as I described above. Is it possible or my approach needs to be changed?


Solution

  • You can - but you need to rearrange everything.

    You should make many-to-manu 'manual' (define custom class like ProductPartDetails etc.),

    Define fluent config for it

    e.g. (more pseudo code)

    [ComplexType()]
    public class Field
    {}
    public class ProductPartDetails
    {
        public int ProductId { get; set; }
        public int PartId { get; set; }
        public virtual Product Product { get; set; }
        public virtual Part Part { get; set; }
        public Field Field { get; set; }
    }
    modelBuilder.Entity<ProductPartDetails>()
        .HasKey(x => new { x.ProductId, x.PartId });
    
    modelBuilder.Entity<ProductPartDetails>()
        .HasRequired(i => i.Product)
        .WithMany(u => u.Details)
        .HasForeignKey(i => i.ProductId)
        .WillCascadeOnDelete(false);
    
    modelBuilder.Entity<ProductPartDetails>()
        .HasRequired(i => i.Part)
        .WithMany(u => u.Details)
        .HasForeignKey(i => i.PartId)
        .WillCascadeOnDelete(false);
    

    Make Details to point now to ProductPartDetails instead of Field.

    ...and add Field to that table as a property.

    Make field ComplexType so it'd be 'reused` (just translates to fields, not table on its own). Something like that for both.

    e.g. EF code-first many-to-many with additional data

    Code First Fluent API and Navigation Properties in a Join Table
    ASP.Net MVC 3 EF "Introducing FOREIGN KEY constraint on table may cause cycles or multiple cascade paths"