Поделиться через


Customizing Entity Classes in VS 2010

When VS 2010 ships it will include some significant improvements to our code generation story for the Entity Framework. The basic idea is to make use of T4 templates for code generation and ship strong integration into the Entity Framework Designer to make the experience of customizing those templates as seamless as possible.

Below Sanjay from our Tools team outlines what will be possible once VS 2010 is released.

Customize the code generated by the Entity Designer with T4 templates

In Visual Studio 2008 SP1, the ADO.NET Entity Designer generates classes from the CSDL portion of the EDMX file using the EntityClassGenerator APIs. Numerous customers have asked us how to customize the code generation for a variety of scenarios including:

  • Make the generated ObjectContext internal
  • Make the generated ObjectContext and Entity classes implement a user-defined interface
  • Add user-defined CLR attributes to generated ObjectContext and generated Entity classes
  • Influence generated classes based on structural annotations in CSDL
  • Generate the ObjectContext and Entity classes into separate files
  • Generate “proxy classes” for the generated classes
  • Partially or fully change how classes are generated, maybe even generate additional (non code) artifacts in the project
  • Completely replace entity framework code generation with custom code
  • Generate POCO classes from the model to use as a starting point in my applications
  • Generate self-tracking entity classes
  • · ...

While the SingleFileGenerator techniques described here enable some of these scenarios these techniques are generally difficult to implement and install or are tricky to debug and customize.

In Visual Studio 2010, we plan to give customers the ability to use T4 templates to generate their classes, and are also planning deep integration with the Entity Designer and Visual Studio to provide a great end-to-end experience.

Walkthrough

The example below customizes code generation to make the generated classes implement a user-defined interface (e.g. IValidate).

Preconditions:

  • User has installed Visual Studio 2010
  • User is familiar with customizing T4 templates
  • User has a C# or a VB console project that targets FX4.0 with an EDMX file in the project

Walkthrough:

  1. User: opens EDMX file in the Entity Designer. Note that the generated classes are in a child file of the EDMX file (i.e. in Northwind.Designer.cs)

    image

  2. User: right-clicks on an empty area of the designer surface and chooses “Add New Artifact Generation Item… ” from the context menu.

    image

  3. Visual Studio: displays the standard “Add New Item” dialog and shows a filtered list of items for the user to select from. As expected, the “Add New Item” dialog only shows a list of item templates specific to the current project target framework version, project type and language.

    image

  4. User: selects “ADO.NET EntityObject Generator”, specifies a file name and clicks “Add"

  5. Visual Studio: checks out the project from Source Control if necessary

  6. Visual Studio: sets the “Custom Tool” property of the EDMX file to empty, which will cause the existing .designer.cs file to be deleted

  7. Visual Studio: the VS item template adds a new .tt file to the project in the same project directory as the EDMX file

    image

  8. Visual Studio: configures the new .tt file to process the selected EDMX file. The EDMX file to process is a replaceable parameter in the .tt file, and VS updates it to point to the selected EDMX file. Thus, the .tt file now knows which EDMX file to generate code for.

    image
    [Screenshot of .tt file open in the Clarius T4 Editor Community edition for VS 2008]

  9. User: double-clicks the .tt file in the project to open it in VS10

  10. User: edits the .tt file in Visual Studio to make every Entity object implement the IValidate interface

    image
    [Screenshot of .tt file open in the Clarius T4 Editor Community edition for VS 2008]

  11. User: saves and closes .tt file

  12. Visual Studio: Transforms the .tt file to produce the generated classes as a child file of the .tt file

  13. User: notes that the generated classes (under the .tt file) implement the IValidate interface as expected

  14. User: switches to the EDMX file in the designer and makes some changes (e.g. add a new entity)

  15. User: saves EDMX file

  16. Visual Studio: Transforms all .tt files in the project that reference the EDMX file. As before, the generated classes are child files of the .tt files

Design

The design affects multiple parts of the Entity Framework and the Entity Designer and the key changes are described below:

Entity Framework Runtime

  1. We started by creating C# and VB T4 templates to generate classes from CSDL and EDMX files
  2. Since the T4 engine is installed with Visual Studio and not with the.NET FX runtime, we preprocess the templates as described here and include the compiled code into System.Data.Entity.Design.dll
  3. We added a new class System.Data.Entity.Design.EntityCodeGenerator (in System.Data.Entity.Design.dll ) that generates code using the preprocessed T4 template
  4. Finally, we enhanced a few runtime metadata APIs and added extension methods to load and iterate over models a lot easier. Our T4 templates make heavy use of these new methods.

Entity Designer

We took the C# and VB T4 templates used by the runtime and changed them to be more “VS friendly” as described below.

  1. We made the EDMX file name referenced in the T4 templates a replaceable parameter
  2. We created a wizard (with no GUI) that is launched by Visual Studio when the item is added to the project. The wizard does 2 things:
    1. updates the EDMX file name referenced in the T4 templates and
    2. sets the “Custom Tool” property of the EDMX file to empty
  3. We rolled up the T4 templates (and wizard) into standard C# and VB Visual Studio item template which are installed with VS 2010; this makes them show up in the “Add New Item” dialog in Visual Studio
  4. We added a new context menu to the designer surface to launch the “Add New Item” dialog and also added code to only show VS item templates whose names start with the prefix ADONETArtifactGenerator_
  5. Our design ensures that user installed VS item templates in %MyDocuments% as well as the VS item templates we ship in box show up in the “Add…New…Item” dialog (per the template name prefix rule above)
  6. We added code to the designer that finds all .tt files related to an EDMX file and automatically transform them when the EDMX file is saved.
  7. Finally, we added a new property called “Process related T4 templates on Save” on the designer surface to let users control whether or not to transform .tt files related to the EDMX file on save.

Multi Targeting considerations

As many of you are aware, VS 2010 allows developers to target FX4.0 as well as FX3.5 (and older runtimes). The T4 templates that we ship in the Visual Studio box generate code that works with the Entity Framework in .NET FX 4.0. This means the VS item templates we ship in the box will not be available for projects that target FX3.5.

However, it is certainly possible (and supported) for users to create new T4 templates (and new VS item templates) that generate code from an EDMX file in projects that target FX3.5 and light up in the same experience. In fact, we might release some new templates ourselves later, on CodeGallery perhaps.

How can 3rd parties plug in?

Since our design is based upon VS item templates that wrap T4 templates, we have opened the door to let 3rd party code generators participate in the end-to-end experience. Our contract is straight forward and easy to implement:

  1. Create a (C# or VB) T4 template to generate code as you desire. The T4 templates we ship in the box can be invaluable points of reference as you roll your own.

  2. Make the EDMX reference in your .tt file a replaceable parameter by calling it $edmxInputFile$ like we do in our .tt file.

  3. Wrap the .tt file in a VS item template. This is pretty easy and well documented on MSDN. You can also use the Export Template wizard included Visual Studio. Also specify additional VS item template settings such as target framework, project type, etc

  4. Prefix the name of your .vstemplate file with ADONETArtifactGenerator_ if you want your VS item template to show up in the “Add New Item” dialog when it is launched from the context menu in the Entity Designer.

  5. You can use the wizard we ship in Visual Studio to do parameter replacement in your VS item template by adding the following to your .vstemplate file:

    <WizardExtension>
      <Assembly>
        Microsoft.Data.Entity.Design, Version=10.0.0.0, Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a
      </Assembly>
      <FullClassName>    Microsoft.Data.Entity.Design.VisualStudio.ModelWizard.AddArtifactGeneratorWizard
      </FullClassName>
    </WizardExtension>

    Of course, you can also create your own wizard that does custom processing when the item is added to the project as described here.

  6. Create a VSCONTENT file and zip up your custom item template & related files into a Visual Studio Content Installer (.vsi) file

  7. Upload the .vsi file someplace your customers can download it from

  8. Visual Studio already knows how to install .vsi files and everything you need is already available in Visual Studio.

A few key takeaways:

  • This design lets the EF team release new T4 templates outside the usual Visual Studio and .NET FX ship cycles and the experience to consume them is exactly the same.
  • There are several excellent resources on the web that describe advanced T4 template scenarios and our design enables them. In fact, we expect users to leverage these resources while creating new T4 templates or customizing the ones we ship. For example, code in a custom T4 template can use the EnvDTE APIs to access the project system and generate outputs to multiple files.
  • Over time, we expect to blog about some of these advanced scenarios and also work with MVPs, industry experts and Patterns & Practices to provide guidance to customers in a manner similar to the Guidance Automation Toolkit.
  • Custom T4 templates can generate anything you want, not just code. For example, we have an internal prototype of a T4 template that iterates over a model and generates an HTML file with a nicely formatted report of the entities and associations in the model
  • VS item templates can add multiple files to your project (more details here). This means your custom item templates can include all kinds of files (e.g. workflow files, multiple T4 files, pre-canned code files, etc). For example, you can easily imagine a 3rd party VS item template that adds 2 .tt files in your project that process the same EDMX file but generate different kinds of outputs.

We hope this gives you an overview of our design and intent of this feature and we would love to hear your comments.

Sanjay Nagamangalam,
Lead PM, ADO.NET Entity Designer

This post is part of the transparent design exercise in the Entity Framework Team. To understand how it works and how your feedback will be used please look at this post .

Comments

  1. "Add New Artifact Generation Item" does not make it totally obvious what the menu option does. "Customize code generation" perhaps?
  2. Give the .tt template the same name as the .edmx file it belongs to; this makes it more obvious what it is for when used in a large and cluttered project.
  3. Show the .tt template as a sub-item to the .edmx file in the project hierarchy. (i.e. set "DependentUpon" in the .csproj/.vbproj file)
  • Anonymous
    January 22, 2009
    ...and one more thing... (I know I said it before, but I think it is worth repeating :)   ) To make the "Influence generated classes based on structural annotations in CSDL" scenario you mentioned possible and more compelling/easier to use in real world scenarios, either: a) allow structural annotation XSDs to be "plugged in" to the designer so that any additional properties can be accessed (viewed and edited) using the property editor. ...and/or... b) add some other kind of extensibility interface to make it possible to view/edit structural annotations directly in the designer. Mockup screenshot showing an example of how that kind of designer extensibility could be used: http://blog.huagati.com/res/wp-content/uploads/2009/01/efDesignerSAMockup.png

  • Anonymous
    January 22, 2009
    @Kristofer: yep, we considered the options you suggested among several others.

  1. "Add New Artifact Generation Item" >> Our design lets users surface custom VS item templates in the "Add New Item" dialog that we launch from the designer as long as they conform to our naming prefix convention. They may or may not have .tt files and may indeed have nothing to do with code generation at all.
  2. Give the .tt template the same name as the .edmx file it belongs to >> Yep, we looked at this and if possible, we might pre-populate a file name when we launch the "Add New Item" dialog from the designer. Users will more than likely want to change the file name so we want to leverage familiar VS paradigms here.
  3. Show the .tt template as a sub-item to the .edmx file in the project hierarchy. >> We had lots of discussions around this. In the end, we felt the ideal user experience was to let the VS item template do what it does by default and not force it to put its files someplace we want. Our design allows users to create VS item templates that may have multiple .tt files (and/or other files) that may process the same or different EDMX file. In such scenarios, users may find it awkward if we forcibly put all files added by the item template as dependent files of the EDMX. We also felt that "grand-children" files in Solution Explorer look a bit strange and may have undesired Source Control consequences (e.g. checking out the EDMX file will also check out the child .tt file, etc). More advanced customizations could include a custom wizard in the VS item template which could put files anywhere in the project hierarchy. Hope this helps answer your questions. Regards, Sanjay
  • Anonymous
    January 22, 2009
    @Sanjay, Thx for the clarification. Re. #1: what I meant was that "artifact generation item" menu name is language that may be crystal clear to the designer of the feature but a first time user will have no clue what it means. And it does not translate very well (to localized versions of VS). #3: Maybe you could solve it with a setting somewhere (e.g. Tools/Options/EDM Designer/...) to control this behavior..? Personally I would like to see the templates that belong to a certain EDMX listed together with it rather than elsewhere in the project hierarchy so if this behavior can be customized that would allow both behaviors.

  • Anonymous
    January 23, 2009
    I was going to write some comments, but Kristofer already said everything I was going to write. Saw to say that I agree with him, especially the part about how this looks like a really, really nice feature.

  • Anonymous
    January 23, 2009
    Will the next designer be able to view subsets of the EDMX, or multiple EDMX's be partial classes of each other? For any significantly sized project there are too many entities for one designer page. thanks, Jason

  • Anonymous
    January 24, 2009
    @Kristofer: Thanks for your feedback. RE: #1: "artifact generation item" menu We've restarted the discussion in the team and will try & come up with a better menu name that is more intuitive to first time users. RE: #2: A "Tools...Options" setting to specify if the files added by the VS item template should be child files of the EDMX seems like a reasonable proposal. However, adding arbitrary files as child files of the EDMX file may not work in all scenarios. Some examples that come to mind are ASP.NET website projects and custom 3rd party VS item templates that add multiple .tt files and/or other files (e.g. code snippets, XAML files, etc) that are in fact not dependent on the EDMX file. Our current design lets 3rd party VS item template & wizard authors do the right thing instead of forcibly making their files dependent files of the EDMX. We’ll certainly look for user feedback and review the design. @Jason: While we understand your scenario, it does not look like the next version of the designer will support viewing subsets of the EDMX at the moment. Can you explain a bit more by what you mean by “multiple EDMX's be partial classes of each other?”. Feel free to send me e-mail at: sanagama –at– microsoft –dot– com Regards, Sanjay

  • Anonymous
    January 25, 2009
    I don’t get it You are doing great work here, but I don’t get it. Diving into the EDMX file or the T4 template is not something I’m eager to do, these files are not user friendly at all, and I know some of you second guess me here. I wish there would be more designer support instead of text support for something simple as breaking the designer into files, or setting the ObjectContext to be internal. Adding an attribute or an interface require more so the T4 seems to be the right way although I can think of other way’s doing it in the CSDL portion. I don’t get it because I’m catching the drift that you are targeting small to medium project and not enterprise one. Since the store procedure support still seems far far away. Things like mapping multiple result sets of sp’s with output params still looks like they’re farfetched. Where scenarios like result set + paging data are very common… Looking at http://blogs.msdn.com/efdesign/archive/2008/07/18/using-stored-procedures-to-get-load-structured-data.aspx does not enlighten things at all Most of the DBA’s I have talked with looks at the EF as a “break point” between the interface they supply (sp’s) and what EF aims for. Sorry for my pessimistic  approach here, still these are my two cents on the subject

  • Anonymous
    January 25, 2009
    @Menny, I think what MSFT is aiming for here is a flexible enough toolset that allow anyone to customize whatever may need customization. On top of that I am sure there will be loads of third party or community built templates and toolkits that add the extra 'bits and pieces' so that not every end-user have to edit their own T4 templates. In short, this is the foundation and template libraries, customization dialogs, add-ins etc goes on top of that. Either as something provided by MSFT, third-parties, or community/open source things on codeplex.

  • Anonymous
    January 26, 2009
    I'm sure it is the foundation but i still think that common tasks like i mentioned should not be integrated via template (T4) editing)

  • Anonymous
    March 02, 2009
    So if you've been reading the Entity Framework Design Blog you will have heard us talk about T4 . It

  • Anonymous
    March 11, 2009
    Will EF 2.0 support the concept of populating an EntitySet from an Insert / Update / Delete Function ? E.g. To support the scenario where an Insert Stored Procedure does an insert into a table followed by Select <fields> from table , which returns multiple rows. ( kind of piggy backing select statement on Insert SP Call ) . Therefore the Insert Function can have a return type as Collection(EntityType). The idea is to avoid making another call to database just to fetch the latest property values for entities.

  • Anonymous
    March 12, 2009
    I'm with Kristofer - I'd definitely rather see the associated .tt files grouped as child items under the .edmx file.  It's much cleaner and less cluttered that way. In response to Sanjay's comments on this: I don't think .tt templates as child items would look strange at all.  In fact it's what I'd expect to see. Regarding source control checking out the child items being undesired - I completely disagree.  I want the child items to also be forcibly checked out.  I don't want my build breaking or wrong code being generated if the templates are missing!

  • Anonymous
    March 23, 2009
    Background One of the biggest pieces of feedback we received from the N-Tier Improvements for Entity

  • Anonymous
    March 23, 2009
    Lots of the feedback we got on the EF design blog about our early N-Tier plans , highlighted that lots

  • Anonymous
    May 06, 2009
    Being a noob and wishing to know more--Can you point me sites, blogs, books, examples for me to learn, use and prepare for VS2010. Any help is appreciated. thanks,

  • Anonymous
    May 06, 2009
    @DZ Zweigle, One of the best resources around for learning about T4 is the blog of Oleg Sych.  Try this out: http://www.olegsych.com/tag/t4/

  • Danny
  • Anonymous
    May 25, 2009
    このところ、書籍の執筆とWindows7でなかなか手に付かなかったのですが、実は次期Visual StudioのBetaがリリースされてます。 Visual Studio 2010 and .NET Framework

  • Anonymous
    June 21, 2009
    So if you&#39;ve been reading the Entity Framework Design Blog you will have heard us talk about T4

  • Anonymous
    August 23, 2009
    hello world in new world ya world ya world

  • Anonymous
    August 23, 2009
    i think entity frame work is good data access but the csla frame work is perfiect to developer to work by it.

  • Anonymous
    January 18, 2010
    The comment has been removed

  • Anonymous
    February 24, 2010
    I would love to see the ability of the Entity Designer itself to have the concept of interfaces, this is a basic object modeling concept. I would like to define my own interface, and then specify which entities implement it. The code generation approach adds the interface to all classes, that is a pretty coarse grained tool.

  • Anonymous
    March 14, 2010
    Sanjay, Is SingleFileGenerator still the best way to implement "Influence generated classes based on structural annotations in CSDL"? We can use T4 in VS2010, however this require having a new template. If I only want to add validation attributes - doesn't matter what template is using - VS2010 doesn't provide any better way, isn't it? Thanks, Bob

  • Anonymous
    September 03, 2010
    I've already tweaked the .tt (and the .ttinclude) so that

  1. it also generates a template for the metadata classes that I can copy to a separate file and add the atributes to
  2. for stored procedures that return no resultset and have OUTPUT parameters generates methods with typed out parameters instead of requiring the user to instantiate the ObjectParameter class and extract the data from there
  3. generates an enum from one of the lookup tables All this worked fine and was not even too complicated. And I plan to release that in case anyone is interested later. I would also like to add the [StringLength()] attribute to the properties comming from varchars and nvarchars, but I'm unable to find out the database type of the properties and the sizes. How do I get to this information from an EdmProperty?
  • Anonymous
    March 25, 2011
    is it possible to use in asp.net applications ?

  • Anonymous
    May 11, 2014
    Entity Interface Generator entityinterfacegenerator.codeplex.com This project contains customized T4 templates which can generate interfaces and attributes for the DbContext class and entity classes.