Recently I wanted to become more familiar with Entity Framework, and MVC.
I'm going to discuss what I learned in a 3 part blog.
Part 1: TPH, Data First, with existing POCO's
Part 2: MVC 4 with existing context class, and an abstract base type
Part 3: MVC 4 view engine, Observer Pattern, and binding
Part 1: TPH, Data First, with existing POCO's
In the past I have worked with NHibernate, and Telirik Open Access ORM's. I have actually used Entity Framework a few times but in very simple scenarios. I follwed the wizards, and let EF create my entities.
I felt that this was pretty unrealistic experience, so I set out to make myself go through some pain so that I could learn the ORM better.
I decided that in many companies I would be asked to map to already existing data and object models.
I already had an existing bookstore demo. This demo included an object model and a data schema. The two were not designed with this EF MVC demo in mind. So I thought I should have to jump through a few hoops to make it work. Well I did.
The model consists of one complex type (an abstract base class called book). And three POCO's (derived book types).
Here is the base class.
Here are the POCO's
Here is the very simple Book table.
I know its not a great idea to directly represent an Enum in a table by it's numeric value. But, I had read EF 5 has better Enum support so I wanted to put it to the test.
First I created an ADO.NET Entity Data Model. By default I ended up with something that looked like this:
The way the model is set now will work, but I don't like it yet. When I get a book out of my database I want it automatically casted to the derived type it really represents. I.E. I want many different types to map to the same table. This is called a "Table-per-hierarchy" design. There is also a Table-per-Type design but I'm not going to go into the differences. To accomplish the behavior I right clicked in the model's blank area, and chose "Add new Entity..." I'm guessing there is some string magic that goes on here so when typing the names of your derived types be sure to spell them the same way you did in your class declarations.
I created PaperBack, Magazine, and HardCover entities and set their base type to "Book"
The map looks like this now:
Almost done, but I need a way for EF to know how to map the derived types when fetching them from the DB. To do this I used a discriminator. In this case "BookTpye" is my discriminator. Right click on BookType in the Book entity, and choose "Delete from model". Now view the mapping details for the PaperBack entity. Click on "Add a condition", I chose BookType and the equals operator, and set the value to 3. This tells EF when the BookType value is three cast the object to PaperBack. I repeated this for Magazine and HardCover.
After that I mapped the Enum's. There is a new "Convert To Enum" option on the right click menu. It brings up a window that looks like this:
And unlike earlier versions of EF this Enum mapping actually works.
Because I chose a code generation strategy of none I have no context class. I chose to implement a context class that inherits from ObjectContext. I could have also used dbContext, but I didn't.
The class itself is easy. The hard part came in troubleshooting various issues I had with my entity connection string's metadata. The problems I had there are a little outside the scope of this blog. I don't want to go too far off on a rabbit trail, but there are several great sites for troubleshooting issues of this type.
Here's the context class:
Here is a class that represents a service layer and exposes functionality of the context class.
Later on I could take this service layer and implement a more traditional SOA approach. I could set it up so that my DO's stay on one side of my service, and DTO's go out to my UI layer. I can set up some object validation in my service layer as well.
With these layers set up I can perform all the basic CRUD functions I need to make a sample MVC application.
As long as I was already in VS 2012 I went ahead and used MVC 4.
I will go over that portion in Part2.
No comments:
Post a Comment