Entity Framework 3 was a bit of a disappointment when it came to supporting enterprise applications. For me the major reason was the fact that entities used by EF required deriving from a class which is part of EF, thus coding the EF requirement into your Business Logic Layer (BLL) and presentation layer.
EF 4 is still under development, but already they’re making a lot of compensation for this with their support for POCO (Plain Old Clr Object) and self tracking objects.
POCO vs. Self Tracking
A self tracking object is an object that has state where you can check what has happened to the object (unmodified, new, modified, deleted). The advantage of this kind of object is simplicity for the user, because the object does all the tracking. Of course this means more work building the object itself, but this can be solved using T4 templates. A POCO is really nothing more than a data carrier object, without any tracking support. Simplicity means maximum portability, especially if you use DataContracts. For the rest of this post I’ll be using self tracking objects, generated through EF 4. I’ll also be using the EF feature CTP 2.
Using EF 4 to generate the self tracking objects
Start by creating a new WinForms project (of WPF, Silverlight, whatever).
Add another library project for your data access layer (DAL) and another one for your entities:
Normally I would also add a business logic layer (BLL) but for simplicity I’ll leave it out for now.
Now add a new Entity Data Model to your DAL project. Select the Northwind database, then select the Categories and Products tables:
This way you end up with this model:
Please note that my tables/entities each have an extra column, the Version column. This is a TimeStamp column used to detect concurrent updates. To tell EF to use this column for concurrency, set its Concurrency Mode property to Fixed. This is typically the best way to handle concurrent updates.
Right-click your entity model’s background, then select the Add Code Generation Item… menu choice:
This alternative code generation will add two T4 templates to the DAL project (using the .tt extension)
The ProductsModel.Context.tt is an EF dependent template, so leave it in the DAL project, but the ProductsModel.Types.tt contains the EF independent types which actually are self-tracking entities. Move this template to the Entities project:
Watch out, your project will not build until you set following references (diagram made with Visual Studio’s new UML Component Diagram) :
This diagram also includes the BLL layer, our solution doesn’t, but if you want, feel free!
If you’re using VB.NET, you should also add the Product.Entities namespace to your list of imports of the DAL project:
Now you’re ready to implement the DAL layer, so add a ProductsDAL class as follows:
1: Public Class ProductsDAL
2:
3: Public Function GetListOfCategories() As List(Of Category)
4: Using db As New NorthwindEntities
5: Return db.Categories.ToList()
6: End Using
7: End Function
8:
9: Public Sub UpdateCategory(ByVal cat As Category)
10: Using db As New NorthwindEntities
11: db.Categories.ApplyChanges(cat)
12: db.SaveChanges()
13: End Using
14: End Sub
15:
16: End Class
Now let’s add some controls and data bind them with Window Forms. For this I use the Data Sources window. Open it and add another data source. Select an object data source:
Then select your Category of Product entity, which you should find in the Products.Entities project:
Your data source window should now display your entities:
Right-click category and select Customize… from the drop-down list.
Now you can select Listbox as the control to use. Drag the Category entity to your form to create a listbox and bindingSource:
Add two buttons, the Load and Save button. Implement the first button to retrieve the list of categories from the DAL:
1: Dim dal As New ProductsDAL
2: CategoryBindingSource.DataSource = dal.GetListOfCategories()
And implement the save button as follows:
1: Dim dal As New ProductsDAL
2: Dim cat As Category = TryCast(CategoryBindingSource.Current, Category)
3: dal.UpdateCategory(cat)
Run the solution and click on load. The listbox should fill with categories and the window should look like this (you might first want to copy the connectionstring in the DAL’s project .config to the form’s config):
Note the “Change Tracking Enabled”. Check the checkbox if you want to update an object, this will enable the self tracking. Make a change, then click Save. This should update the database.
Open two instances of this application. Load in both, then change the same record in both (with tracking enabled). Save both. The second Save should fail because of concurrency checking.
Done!