T4 Templates in Entity Framework 4

December 5, 2009

T4 Templates in Entity Framework 4

T4 templates orT4 Templates in Entity Framework 4
Text Template
Transformation Toolkit
is
a mean of creating a code
generation
artifacts which
can save a lot of time.
This technology is a part of
Visual Studio since 2005 but
was one of those technologies
that were kept in secret by Microsoft.
Almost all the code generation stuff that is being used
in Visual Studio in technologies such as MVC, Entity Framework,
LINQ to SQL and many other use those templates as backbone
to generate code. In this post I’m going to show one of the
new features of EF4 which is the use of T4 templates to extend
or manipulate the code generation. If you like to read more about
T4 templates I recommend Scott Hanselman’s post – 
T4 (Text Template Transformation Toolkit) Code Generation –
Best Kept Visual Studio Secret
which has many references to good
reading stuff.

T4 Templates in Entity Framework 4 Example

In EF4 we can use T4 templates to extend and manipulate the
code generation. In the example I start with a very simple
console application. That application has a Entity Data Model
which is the same School model that I used for all my previous
EF posts:
Solution Explorer 

Adding a T4 Template

Now lets explore the process of using the T4 templates.
In order to use the T4 templates, from the Entity Framework
Designer
surface use the right mouse button to open the menu
and choose the Add Code Generation Item menu item:
Add Code Generation Item 
This will open the Add New Item window that holds only EF4 T4
templates
:
Add New Item
As you can see I have two T4 templates that I can generate. I choose the
ADO.NET EntityObject Generator. A security warning will be popping up to
check if you trust the source that generated the T4.
Security Warning
I choose to continue and a new file with the extension .tt is added to
the solution.
After Adding the T4 Template
When you observe the generated .tt file you can see that all the generated
stuff of EF is located in a new .cs file that is attached to it. When opening  
the SchoolModel.Designer.cs file that is attached to the edmx file you will
see a comment that say it is no longer being used:

// Default code generation is disabled for model 'path\SchoolModel.edmx'. 
// To enable default code generation, change the value of the 'Code Generation Strategy' designer
// property to an alternate value. This property is available in the Properties Window when the model is
// open in the designer.

Now that we have our own code generation file we can start manipulating

the generated code.

Manipulating Generated Code Using a T4 Template

Say for example that I want to remove the generated OnContextCreated

method which is called from the ObjectContext’s constructors:

/// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    public partial class SchoolEntities : ObjectContext
    {
        #region Constructors
    
        /// <summary>
        /// Initializes a new SchoolEntities object using the connection string found in the 'SchoolEntities' section of the application configuration file.
        /// </summary>
        public SchoolEntities() : base("name=SchoolEntities", "SchoolEntities")
        {
            this.ContextOptions.LazyLoadingEnabled = true;
            OnContextCreated();
        }
    
        /// <summary>
        /// Initialize a new SchoolEntities object.
        /// </summary>
        public SchoolEntities(string connectionString) : base(connectionString, "SchoolEntities")
        {
            this.ContextOptions.LazyLoadingEnabled = true;
            OnContextCreated();
        }
    
        /// <summary>
        /// Initialize a new SchoolEntities object.
        /// </summary>
        public SchoolEntities(EntityConnection connection) : base(connection, "SchoolEntities")
        {
            this.ContextOptions.LazyLoadingEnabled = true;
            OnContextCreated();
        }
    
        #endregion
    
        #region Partial Methods
    
        partial void OnContextCreated();
    
        #endregion
    
        #region ObjectSet Properties
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        public ObjectSet<Course> Courses
        {
            get
            {
                if ((_Courses == null))
                {
                    _Courses = base.CreateObjectSet<Course>("Courses");
                }
                return _Courses;
            }
        }
        private ObjectSet<Course> _Courses;
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        public ObjectSet<Department> Departments
        {
            get
            {
                if ((_Departments == null))
                {
                    _Departments = base.CreateObjectSet<Department>("Departments");
                }
                return _Departments;
            }
        }
        private ObjectSet<Department> _Departments;
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        public ObjectSet<Enrollment> Enrollments
        {
            get
            {
                if ((_Enrollments == null))
                {
                    _Enrollments = base.CreateObjectSet<Enrollment>("Enrollments");
                }
                return _Enrollments;
            }
        }
        private ObjectSet<Enrollment> _Enrollments;
    
        /// <summary>
        /// No Metadata Documentation available.
        /// </summary>
        public ObjectSet<Person> People
        {
            get
            {
                if ((_People == null))
                {
                    _People = base.CreateObjectSet<Person>("People");
                }
                return _People;
            }
        }
        private ObjectSet<Person> _People;
 
        #endregion
        #region AddTo Methods
    
        /// <summary>
        /// Deprecated Method for adding a new object to the Courses EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
        /// </summary>
        public void AddToCourses(Course course)
        {
            base.AddObject("Courses", course);
        }
    
        /// <summary>
        /// Deprecated Method for adding a new object to the Departments EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
        /// </summary>
        public void AddToDepartments(Department department)
        {
            base.AddObject("Departments", department);
        }
    
        /// <summary>
        /// Deprecated Method for adding a new object to the Enrollments EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
        /// </summary>
        public void AddToEnrollments(Enrollment enrollment)
        {
            base.AddObject("Enrollments", enrollment);
        }
    
        /// <summary>
        /// Deprecated Method for adding a new object to the People EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
        /// </summary>
        public void AddToPeople(Person person)
        {
            base.AddObject("People", person);
        }
 
        #endregion
    }

Opening the .tt file and then removing the OnContextCreated

method call from the constructors and also the generation of the

OnContextCreated partial method will result in the following

ObjectContext:

/// <summary>
/// No Metadata Documentation available.
/// </summary>
public partial class SchoolEntities : ObjectContext
{
    #region Constructors
 
    /// <summary>
    /// Initializes a new SchoolEntities object using the connection string found in the 'SchoolEntities' section of the application configuration file.
    /// </summary>
    public SchoolEntities() : base("name=SchoolEntities", "SchoolEntities")
    {
        this.ContextOptions.LazyLoadingEnabled = true;
    }
 
    /// <summary>
    /// Initialize a new SchoolEntities object.
    /// </summary>
    public SchoolEntities(string connectionString) : base(connectionString, "SchoolEntities")
    {
        this.ContextOptions.LazyLoadingEnabled = true;
    }
 
    /// <summary>
    /// Initialize a new SchoolEntities object.
    /// </summary>
    public SchoolEntities(EntityConnection connection) : base(connection, "SchoolEntities")
    {
        this.ContextOptions.LazyLoadingEnabled = true;
    }
 
    #endregion
 
    #region ObjectSet Properties
 
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    public ObjectSet<Course> Courses
    {
        get
        {
            if ((_Courses == null))
            {
                _Courses = base.CreateObjectSet<Course>("Courses");
            }
            return _Courses;
        }
    }
    private ObjectSet<Course> _Courses;
 
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    public ObjectSet<Department> Departments
    {
        get
        {
            if ((_Departments == null))
            {
                _Departments = base.CreateObjectSet<Department>("Departments");
            }
            return _Departments;
        }
    }
    private ObjectSet<Department> _Departments;
 
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    public ObjectSet<Enrollment> Enrollments
    {
        get
        {
            if ((_Enrollments == null))
            {
                _Enrollments = base.CreateObjectSet<Enrollment>("Enrollments");
            }
            return _Enrollments;
        }
    }
    private ObjectSet<Enrollment> _Enrollments;
 
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    public ObjectSet<Person> People
    {
        get
        {
            if ((_People == null))
            {
                _People = base.CreateObjectSet<Person>("People");
            }
            return _People;
        }
    }
    private ObjectSet<Person> _People;
 
    #endregion
    #region AddTo Methods
 
    /// <summary>
    /// Deprecated Method for adding a new object to the Courses EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
    /// </summary>
    public void AddToCourses(Course course)
    {
        base.AddObject("Courses", course);
    }
 
    /// <summary>
    /// Deprecated Method for adding a new object to the Departments EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
    /// </summary>
    public void AddToDepartments(Department department)
    {
        base.AddObject("Departments", department);
    }
 
    /// <summary>
    /// Deprecated Method for adding a new object to the Enrollments EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
    /// </summary>
    public void AddToEnrollments(Enrollment enrollment)
    {
        base.AddObject("Enrollments", enrollment);
    }
 
    /// <summary>
    /// Deprecated Method for adding a new object to the People EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
    /// </summary>
    public void AddToPeople(Person person)
    {
        base.AddObject("People", person);
    }
 
    #endregion
}

Of course this is silly to do because this is an extension point

when the context is being created but for the example it is enough

to show the power of the T4 templates.

Summary

The T4 templates enables us to implement code generation.

When you have something that you do manually more then one time

then applying a T4 template can help you to make it automatic.

As I show in the post, EF4 is shipping with a way to manipulate the

code generation using T4 templates. Next time when something bother

you in the EF generated code you can do something about it.

DotNetKicks Image
Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

one comment

  1. Pingback: Entity Framework Model First: using ntext to get around 4000 chars length limit