2
votes

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?

1
have you tried ? and what doesn't work - NSGaga-mostly-inactive
I would like to know the fluent api. Currently a Table "Field" gets created and shared with both Product and Promotion with ForeignKeys. - Ahuman
I hear you :) 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. HasRequired(...).WithMany(...) and .HasKey(...) 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. If you can try something yourself based on this - I don't have time right now - and I'll take a look what you did and feel in the gaps. - NSGaga-mostly-inactive
e.g. > here <, or take a look at CategoryItemValue > here < - NSGaga-mostly-inactive
and you are 'over 15' now - welcome to 'voters' - NSGaga-mostly-inactive

1 Answers

1
votes

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"