How does the ADO.NET Entity Designer generate code?

Published 24 January 08 10:01 AM | dpblogs 

 

I’ve had this article pending for a while; numerous folks wanted more information on this topic and I finally got some this weekend and wrote it up for your reading pleasure.

The ADO.NET Entity Designer stores all its information in the EDMX file which merely encapsulates the EF metadata artifacts (CSDL/MSL/SSDL content) along with a bunch of designer data in a single file. I’ve described the structure of the EDMX file in a previous post.

Background

The ADO.NET Entity Designer generates data classes from the CSDL portion of the EDMX file. We extract the CSDL from the EDMX in a manner similar to what I’ve described in this post . Assuming there are no errors during code generation, these classes are immediately visible in the project and are ready for consumption in the project. There are 2 parts to how the designer generates code:

1.       We register a generator (called EntityModelCodeGenerator) with Visual Studio using a standard extensibility mechanism called SingleFileGenerator. Visual Studio calls EntityModelCodeGenerator as necessary when the content of the EDMX file changes.

2.       The EntityModelCodeGenerator in turn extracts the CSDL from the EDMX and calls public code generation APIs in the EntityClassGenerator class (in the System.Data.Entity.Design namespace) to generate code in the required project language.

If you select any EDMX file in Solution Explorer and look at the Visual Studio property window, you’ll see that it’s “Custom Tool” property is set to EntityModelCodeGenerator. This tells Visual Studio to call our generator when the content of the EDMX file changes.

SingleFileGenerator

A SingleFileGenerator is basically a COM component that implements the IVsSingleFileGenerator interface. Visual Studio 2008 has a number of SingleFileGenerators: MSDataSetGenerator, ResXFileCodeGenerator , SettingsSingleFileGenerator, etc are all SingleFileGenerators. Linq to SQL uses a SingleFileGenerator too (called MSLinqToSQLGenerator).

Before the mention of COM scares you away, there’s tons of great information on SingleFileGenerators and Visual Studio extensibility on MSDN and the Visual Studio 2008 SDK has an excellent SingleFileGenerator sample that you can use as a starting point for your own. For most purposes, you can copy/paste the sample in the VS 2008 SDK, do what you need in the GenerateCode() override, register the SIngleFileGenerator and you are pretty much done (trust me!).

While I won’t dwell on the finer points of VS extensibility and SingleFileGenerators, I will note that the contract for a SingleFileGenerator is pretty straight forward. After it is registered correctly with Visual Studio, every SingleFileGenerator is required to override the GenerateCode() method whose signature looks as follows from the VS 2008 SDK sample:

protected override byte[] GenerateCode(string inputFileContent)

The overall flow is as follows:

·         Visual Studio calls your GenerateCode override with the file buffer contents when needed (e.g. when buffer contents change, file save, project build, active window changes, etc).

·         In your override, you look at the file buffer contents, do whatever processing you need and give a byte array with the generated code back to Visual Studio.

·         Visual Studio takes your byte array and puts it into a “code behind” file in the project. For example, the Model1.edmx has its generated code in Model1.Designer.cs or Model1.Designer.vb depending on the project language.

A SingleFileGenerator has access to the Visual Studio error list and can report errors/warnings. Visual Studio manages double-click behavior for errors/warnings reported by a SingleFileGenerator by taking you to the offending line/column in the correct file. A SingleFileGenerator also has access to the project system in case you want to, say; traverse the list of project items in a particular folder, etc. Visual Studio manages the lifetime of the “code behind” file and is also responsible for additional project housekeeping things like Source Control interaction.

Since the ADO.NET Entity Designer leverages the SingleFileGenerator extensibility point, you can replace our SingleFileGenerator with one you create by simply setting the “Custom Tool” property of the EDMX file to a customized generator of your choosing.

I’ll explore scenarios where this is interesting in a separate blog post.

 Sanjay Nagamangalam
Program Manager, ADO.NET

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Mike Taulty's Blog said on January 25, 2008 4:36 AM:

Entity Framework Toolkits & Extras How Does The Entity Designer Generate Code? How To Extract CSDL...

# Marcelo's WebLog said on January 25, 2008 2:05 PM:

I admit it - sometimes I fall in love very hard with some of my tools. Tools that make me productive.

# ADO.NET team blog said on January 25, 2008 4:22 PM:

In previous posts, I’ve described CSDL annotations , how to extract CSDL from EDMX and introduced you

# BjartN said on February 14, 2008 7:17 AM:

When can we expect full oracle support in the entity designer like creating entities directly from the oracle database the way we can with mssql databases.

# dcazzulino said on May 12, 2008 11:57 AM:

Using SingleFileGenerators is bad for continuous integration and automated build processes.

WPF and XML (i.e. Linq to XSD) teams are moving away from them and switching to custom compile actions and MSBuild tasks, which integrates much better with a build process.

How would you integrate this with the build process?

# Ido Flatow said on June 20, 2008 7:11 AM:

כפי שאתם יודעים, אחד מהחידושים של C# 3.0 הוא Partial Method שמאפשר לנו לכתוב מתודות Partial ולממשן (או

# Mihai said on February 27, 2009 9:12 AM:

@dcazzulino: I suppose you don't. The promise of the generator is that it automates certain tasks upstream of the build system.

It's reasonable to assume that the team members are smart enough to build the solution (if not run a unit test, or integration test, in the case of EDMX) before pushing any changes into the source control system. In other words, before the integration build takes a look at it.

That said, I do see the value of having the integration build as a last line of defense.

Custom build actions are a terrible choice, and although we're far from seeing .NET fulfill the promise of write once, run anywhere, it should be clear that the presence of any Windows-specific post-build action indicates a procedural smell. Custom build actions tie you right back into Windows crap.

As far as MSBuild tasks, if Visual Studio makes it easy to work with such custom tasks, then it sounds like a good idea. Otherwise... well, I'll take the SingleFileGenerator.

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required

Search

This Blog

Syndication

Page view tracker