3

In my application users can define Parameters, and then create SlideSets based on a grouping of parameters.

I am using code-first Entity Framework 5.0 and I have the following model:

slideset references several parameters

class SlideSet {
  public ICollection<Parameter> Parameter
}
class Parameter {}

A parameter might be used by many slidesets or none at all. However, in my domain a parameter has no need to reference a SlideSet, they are in separate bounded contexts (both SlideSet and Parameter are Aggregate Roots). As such, I don't want to put a reference from Parameter to SlideSet.

The table model (I don't care about table/column names) that I want is

Table SlideSet
Table Param
Table SlideSetParam
   FK_SlideSet
   FK_Param

I know I could model this by introducing a ParameterGroup entity or a Param.SlideSets collection, but it would exist solely for ORM mapping purposes (and cause serialization issues). Is there any other way to tell EF to generate this table model from my entities?

George Mauer
  • 117,483
  • 131
  • 382
  • 612
  • I think what you are looking for is this: http://stackoverflow.com/questions/8927278/how-to-configure-many-to-many-relationship-using-entity-framework-fluent-api#answer-8927446 – educampver Mar 31 '13 at 05:06
  • I think you should take some side effects of using ORM for granted. You can prevent serialization problems by making the collection not lazy loading. – Gert Arnold Mar 31 '13 at 10:10

1 Answers1

3

This should make you a Parameter w/o a navigation property:

modelBuilder.Entity<SlideSet>()
    .HasMany(x => x.Parameters)
    .WithRequired();

EDIT:

Based on the comment - that should be all together similar. This seems to work nicely what you're trying to do....

modelBuilder.Entity<SlideSet>()
    .HasMany(x => x.Parameters)
    .WithMany();

...and you can use it either way:

var slideset = new SlideSet { Parameters = new []
    {
        new Parameter{},
        new Parameter{},
        new Parameter{},
        new Parameter{},
    }
};
var slideset2 = new SlideSet { };
db.SlideSets.Add(slideset);
db.SaveChanges();

var slidesets = db.SlideSets.ToList();
var parameters = db.Parameters.ToList();
Console.WriteLine("");

db.SlideSets.Add(slideset2);
db.SaveChanges();

slidesets = db.SlideSets.ToList();
parameters = db.Parameters.ToList();
Console.WriteLine("");

...and the SQL:

CREATE TABLE [dbo].[Parameters] (
    [ParameterID] [int] NOT NULL IDENTITY,
    CONSTRAINT [PK_dbo.Parameters] PRIMARY KEY ([ParameterID])
)
CREATE TABLE [dbo].[SlideSets] (
    [SlideSetID] [int] NOT NULL IDENTITY,
    CONSTRAINT [PK_dbo.SlideSets] PRIMARY KEY ([SlideSetID])
)
CREATE TABLE [dbo].[SlideSetParameters] (
    [SlideSet_SlideSetID] [int] NOT NULL,
    [Parameter_ParameterID] [int] NOT NULL,
    CONSTRAINT [PK_dbo.SlideSetParameters] PRIMARY KEY ([SlideSet_SlideSetID], [Parameter_ParameterID])
)
CREATE INDEX [IX_SlideSet_SlideSetID] ON [dbo].[SlideSetParameters]([SlideSet_SlideSetID])
CREATE INDEX [IX_Parameter_ParameterID] ON [dbo].[SlideSetParameters]([Parameter_ParameterID])
ALTER TABLE [dbo].[SlideSetParameters] ADD CONSTRAINT [FK_dbo.SlideSetParameters_dbo.SlideSets_SlideSet_SlideSetID] FOREIGN KEY ([SlideSet_SlideSetID]) REFERENCES [dbo].[SlideSets] ([SlideSetID]) ON DELETE CASCADE
ALTER TABLE [dbo].[SlideSetParameters] ADD CONSTRAINT [FK_dbo.SlideSetParameters_dbo.Parameters_Parameter_ParameterID] FOREIGN KEY ([Parameter_ParameterID]) REFERENCES [dbo].[Parameters] ([ParameterID]) ON DELETE CASCADE

...this makes the original tables practically 'agnostic' of the relationships (many-to-many) - while index table is automatically generated in the background.

You can also further customize that and make your own SlideSetParam (e.g. if you'd want to add additional fields there) with pretty much the same layout - just Parameters would have to point to that instead.

NSGaga-mostly-inactive
  • 14,052
  • 3
  • 41
  • 51
  • Thanks but - with this db structure a Slideset can have many Parameters but a Parameter can be used by at most one Slideset. In my case a Parameter can be used by zero or many Slidesets and a Slideset can have zero or many Parameters. I just don't want the Parameter object to reference Slideset. – George Mauer Mar 31 '13 at 02:57
  • It was late :) - I didn't get that other point - it is quite similar though - I revised it. – NSGaga-mostly-inactive Mar 31 '13 at 11:32
  • Oh cool, I'll try this today but this looks like what I want thanks – George Mauer Mar 31 '13 at 13:25