2

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?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Ahuman
  • 752
  • 6
  • 18
  • have you tried ? and what doesn't work – NSGaga-mostly-inactive Apr 06 '13 at 00:18
  • I would like to know the fluent api. Currently a Table "Field" gets created and shared with both Product and Promotion with ForeignKeys. – Ahuman Apr 08 '13 at 13:59
  • 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 Apr 08 '13 at 15:13
  • e.g. [> here <](http://stackoverflow.com/questions/10154512/code-first-fluent-api-and-navigation-properties-in-a-join-table/10155439#10155439), or take a look at `CategoryItemValue` [> here <](http://stackoverflow.com/questions/10254677/asp-net-mvc-3-ef-introducing-foreign-key-constraint-on-table-may-cause-cycles-o/10255184#10255184) – NSGaga-mostly-inactive Apr 08 '13 at 15:16
  • and you are 'over 15' now - welcome to 'voters' – NSGaga-mostly-inactive Apr 08 '13 at 15:31

1 Answers1

1

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"

Community
  • 1
  • 1
NSGaga-mostly-inactive
  • 14,052
  • 3
  • 41
  • 51
  • Actually I was looking for fluent api to map same ComplexType into different tables. But I ended up creating custom classes inheriting Field entity and mapping them for one to many as you suggested. Thanks for the response. – Ahuman Apr 08 '13 at 15:34
  • Complex types are not mapped - just use it as 'composite' part - and you don't need `ID` - ID will be made (like any of its properties) into Field_ID, Field_Name, Field_Value etc. – NSGaga-mostly-inactive Apr 08 '13 at 15:36