What’s New in Entity Framework 4? API Changes(1)(转)
If you have been working with the ADO.NET Entity Framework, you have probably been extremely eager to get your hands on the next version that is now part of Visual Studio 2010 and .NET 4.0. Long referred to as “EF Version 2,” this version is now called Entity Framework 4 or EF4, to align with the .NET Framework 4.0 version.
Microsoft released Visual Studio 2010 Beta 1 in mid-May along with .NET Framework 4.0 Beta 1 and many developers have been digging deeply. VS 2010 offers many new features, but this article will focus on new features and improvements in the ADO.NET Entity Framework (EF). Although this is only the second version of EF, it’s version number is 4, to align with the .NET version, therefore many people call it EF4.
The changes in EF4 include numerous major improvements to the designer, the addition of model-first design, a new way to customize classes that are generated from the model, the ability to create POCOclasses (Plain Old CLR Objects) that can be used in EF without having to be strongly bound to the EF APIs, and additions that will make using entities across processes (e.g. Web services) much easier for developers. I will highlight some of the bigger and more interesting features in the APIs. A future article will highlight designer changes and the tools released in the out of band Feature Pack.
Note that this article is not meant to be a primer on Entity Framework and therefore assumes that you have some experience working with the current version. Yet, rather than give only a high level overview of the new features, this article will give you insights into using a number of the new features.
Generating Custom Classes from a Model
Once you have designed an Entity Data Model, the designer triggers a code generator, which builds classes from the entities defined in the model. In the first version of Entity Framework, this code generation was handled by code in the System.Data.Entity.Design API. If you wanted to customize the generated code, it meant learning that API and writing your own code generation methods-a somewhat cumbersome task. For EF4, the team has leveraged a code generator that was introduced in Visual Studio 2008 called T4 (Text Template Transformation Toolkit). See the Resources sidebar for more information on T4 in general. Using T4 templates makes customizing the generated entity classes enormously simpler.
To demonstrate this, I’ll begin with a simple model to track my bike rides as shown in Figure 1.
Figure 1: Starting with a simple model.
There are two steps to this customization. First you need to get access to the default template file that is used to generate the classes. If you look at the MSDN documentation on T4, the topic title is “Generating Artifacts by Using Text Templates.” This knowledge helps make context menu option, Add New Artifact Generation Item...more obvious as the item to choose. Microsoft will change this post-Beta to a more clear description.
When you select this option, the wizard will open the Add Item dialog with the ADO.NET EntityObject Generator selected giving it a default name with the “tt” extension. Currently there is only one template available, but look for more templates to show up in the future iterations of Visual Studio 2010.
You’ll see the new template file in the Solution Explorer as shown inFigure 2. Additionally, notice that there is no longer a code file attached to the edmx file. Since the template is now responsible for generating the classes, the class file is attached to the template file.
Figure 2: This highlighted T4 template controls the code generation for the BikeRides.edmx model.
If you select the model in Solution Explorer, you’ll see in its property window that the Custom Tool property is now empty. The default generator, EntityModelCodeGenerator, will no longer be used. If you want to revert back to the default, you can just re-enter the default value and EF will take care of the rest.
Now that you have the template file accessible you can begin modifying it. Since my project is C#, the C# template was pulled in but there is also a template written in Visual Basic.
VS 2010 doesn’t have a built-in T4 editor, but you’ll find a number of third-party tools that make editing the template file easier. The T4 code listings that follow are formatted using tangible’s T4 Editor, which I have installed. See the Resources sidebar for info on T4 editors.
A T4 template has two types of content. The first is straight text, which is written directly to the target file. The second is executable code, called a directive, which is embedded in a pair of angle brackets with hash signs.
The directive will process some logic and write out the text that is the result of that logic. If you are used to working in HTML markup, this may look familiar.
This code snippet shows a directive that calls a method defined later in the T4 template.
># BeginRegion("Entities"); #>This directive outputs a starting region tag in the generated code.
#region EntitiesIt might be helpful to compare the generated code file with the template to get an idea of how the template is built.
Let’s focus on the template section that generates a BikeRoute class and one of its properties, RouteName, shown in Listing 1.
The snippet below shows the template code that iterates through each entity in the model and writes out the class declaration.
First, you’ll see a directive with a comment in it that begins to look at the entities. Note that the color-coding for the T4 code is provided a Visual Studio extension by tangible Engineering called tangible T4 Editor. See the sidebar, Resources-T4, for more info.
<#////////
//////// Write EntityType classes
////////
BeginRegion("Entities");
foreach(EntityTypeWrapper entity
in Edm.SourceEntities
.OrderBy(e => e.ModelName))
{
#>
After the end of the first directive, the template writes the beginning summary tag to the class file and then uses another directive to determine what goes into the summary comments.
/// <summary>/// <#=entity.SummaryComment#>
/// </summary>
Next, another directive looks to see if there is a LongDescription for the entity and if so, writes that out.
<#=entity.GetLongDescriptionComment(_regionIndentLevel)#>
Now some more text is written followed by the model namespace, which is determined by another directive.