Last week, a colleague of mine asked me to create a sample composite design pattern model in Entity Framework. I thought to myself, no problem, created the table that contains the Component, Leaf & Composite entities (according to TPH – Table Per Hierarchy) and went to build the EDM based on the table and there I started to have problems which needed manual fixing. Since I’m working with EF 3.5, I’ve built the DB prior to the model – In EF 4.0 you can do model-first and build your db by script.
After reverse engineering the db table, I got one entity named “CompositePattern”. From there I had to do some things in the designer and some things manually:
-
In the designer, change the name of “CompositePattern” to “Component”.
-
Mark the entity abstract.
-
Create a new entity, called “Leaf” and base it on the “Component” entity.
-
Move the required properties from the “Component” type to the “Leaf” type by cutting & pasting the scalar properties (You may need to set the mappings for the properties you’ve moved).
-
Create a new entity, called “Composite” and base it on the “Component” type.
-
Now comes the tricky part – moving the children relation from the “Component” type to the “Composite” type. This cannot be done in the designer, only straight in the XML itself.
-
Before changing the navigational property, note that there are two navigational properties for the composite->component relation - one on each side: a navigational property “Children” from “Composite” to “Component”, and another navigational property “Parent” from “Component” to “Composite” – This is what we’ll need to change in the EDMX file.
-
Open the EDMX file with a xml editor (right-click the .EDMX file and choose “Open with…” and select “XML Editor”.
-
Since EF’s wizard didn’t name the navigational properties correctly, we’ll start by finding and replacing them. You can identify which navigational property is the parent and which is the children according to the multiplicity – the “Parent” should be marked as “0..1” and the “Children” should be marked as "*” (in my case it was “CompositePattern” and “CompositePattern1” accordingly) – Locate all the occurrences of these names and replace them with “Parent” and “Children” accordingly.
-
Now that we named the navigational properties and associations, we ca start changing things. The changes are only in the CSDL part:
-
Locate the association element for the composite->component relation (If you’re working in a new model, you should have only one association element) - Change the type of “Parent” to “Composite” (because parents are always of type composite)
-
Locate the “Children” navigation property in the “Component” type and move it to the “Composite” type.
-
Close the file. You can try to open it again in the designer, for me it did not work with EF 3.5 and VS 2008 SP1, but did work with EF 3.5 and VS 2010 Beta 2.
Write some code to insert composites and leafs and see how it works.
If you got mixed up and didn’t manage to create the composite model, no fear – the sample model can be downloaded from here.
The sql for building the db table (In SqlServer) is:
CREATE TABLE [dbo].[CompositePattern](
[ID] [uniqueidentifier] NOT NULL,
[FirstName] [varchar](50) NULL,
[LastName] [varchar](50) NULL,
[ParentID] [uniqueidentifier] NULL,
[Type] [int] NOT NULL,
CONSTRAINT [PK_CompositePattern] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF
, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
I will continue to post some more Entity Framework tips & tricks this week while I'm attending the
PDC, and of course post about the new stuff discussed in the conference.
Just to remind you all, in December we’re having the SDP where we will talk a lot about Entity Framework and ORM in general, don’t forget to register.