This post covers Code Only improvements in the CTP3 release for VS 2010 Beta2. This walkthrough shows how you can change the default model like specifying property facets and navigation property inverses as well change the default mapping by changing the default inheritance strategy and table and column names. You can learn more about Code-Only improvements from our blog post.
Steps 1 to 9 cover getting started with the project. If you are familiar with the earlier CTP of Code Only and want to see some of the improvements in CTP2, please jump to Step 10.
1) Create a Console Application called “CodeOnlyWalkthru”:
2) Add a new Project to the “CodeOnlyWalkThru” solution:
3) Choose ‘Class Library’ and call the library “Blogging”:
Our Blogging library will consist of the following classes
4) Add the required classes in the Blogging project:
Right click on the project and add a class called “Blog” and then paste this code into the class
In the Blog class right click on the reference to the non-existent Post and class choose “Generate > Class” from the context menu. Paste the code below into the generated class
In a similar fashion, add the Comment class and paste this code into the class
Add the Person class and then paste this code into the class
Right click on the project and add a class called “User” and then paste this code into the class
Your project should now look like this:
We are keeping these blogging classes in a separate project so they are compiled into an assembly that has no dependencies on the Entity Framework. The Blogging assembly is therefore persistence ignorant, which is very important for some developers. The persistence aware code lives in a separate assembly which references the persistence ignorant assembly.
6) In the “CodeOnlyWalkThru” Project add references to the Blogging Project, System.Data.Entity and Microsoft.Data.Entity.Ctp.
7) In the “CodeOnlyWalkThru” project add a new class called “BloggingModel” and paste this code in the class:
Since this class extends ObjectContext, it represents the shape of your model and acts as the gateway to your database. We added a constructor that takes an EntityConnection, which is a wrapper around the real database connection and the Entity Framework metadata, and pass it to this constructor when we ask it to create a new instance of our BloggingModel.
8) Now create BloggingDemo class and paste the code below:
This code creates “Blogging” database and also creates a blog entry, a post and a comment. We are also creating a ContextBuilder which infers the Conceptual Model, Storage Model and Mapping. It uses that metadata plus the SqlConnection you passed in to create an EntityConnection, and finally it constructs the context(BloggingModel) by passing in the EntityConnection to the constructor.
The interesting method is RegisterConfigurations. This method uses the improvements in the CTP which allows us to customize the model as well as the mapping.
9) Paste the code for the RegisterConfigurations method:
Note that we have created classes to encapsulate the configuration for each type. Each configuration class derives from EntityConfiguration<TEntity> and the constructor contains all the configuration logic. This is the preferred approach as it encapsulates and makes the code easier to read.
10) Add CommentConfiguration class to the project and paste the below code:
We have defined this class to contain the entire configuration for the comment class. We want to ensure the Primary Key is store generated which we do using IsIdentity(). We also specify additional property facets like specifying the Maxlength on the title and Body, Author and Post are required.
We also register inverses here. We are indicating that Comment.Post is the other end of the Post.Comments relationship. Adding comment1 to the post1.Comments collection has the same effect as setting the comment1.Post to post1.
We specify a similar inverse relationship between Comment.Author and Author.comments.
11) Add BlogConfiguration class to the project and paste the code below:
We are indicating that the ID is an identity column and other property facets.
We are also specifying inverse relationships between the Blog.Owner and Owner.Blogs and between Blog.Posts and Post.Blog.
12)Add PostConfiguration class and paste the code below:
Code-Only in CTP2 allows assigning Foreign Key property with a navigation property, which is what we are doing at the end of the constructor. This says Post.Blog and Blog.Posts are inverses and that Post.BlogID and Blog.ID must be the same , which implies Post.BlogID is a FK property.
13) Add the PersonConfiguration Class and paste the code below:
Apart from specifying some property facets, we are also specifying the inheritance hierarchy. Code Only by convention follows TPH which generates a table per hierarchy. This would have resulted in both Person and User being stored in the same table.
If we want to instead have Person and User stored in different tables, we can specify that using MapHierarchy. We are also changing the default column names to email, fn, ln instead of EmailAddress, FirstName and SurName. Finally we indicate that we want all of this to be stored in a “People” table.
14) Add the UserConfiguration class and paste the code below:
Here we want the specify a column name with spaces in it , so we are using the EntityMap to specify the “u i d” column name. EntityMap provides an alternate mapping syntax when we need to override CLR limitations.
We are also specifying some property facets for Password and some inverse relationships.
15) Call BloggingDemo.Run(). Paste the code into Program.cs
In this walkthrough we have covered some of the improvements in Code Only that allow us to make more fine grained control over our model and also customize our mappings. We looked at how to specify property facets and also relationship inverses and Foreign Keys.
We changed the default inheritance strategy of TPH to TPT also specified the Table and Column names instead of the default generated names.
Some of the features that are in the CTP2 but not covered by the WalkThrough include Complex Types, Join Table Mapping and Entity Splitting. Please refer to the blog post on how to use these features.
We are looking forward to hearing your feedback on new Code Only Improvements.