Archive for the ‘Entity Framework’ Category

We’re Hiring! Test Positions Open on Entity Framework and WCF Data Services (Astoria) Teams

January 27th 2010

With work on Visual Studio 2010 winding down, both the Entity Framework and Astoria teams have test engineer positions open. Here are the job postings:

Note: If the job descriptions above still say you need C/C++ experience, this is not true. If you don’t have experience in these areas, don’t let that discourage you from applying! In fact, I didn’t have C/C++ experience upon arriving here…

Now, I know what you’re thinking—"ugh, test, you mean those guys who sit on the other side of the building and click on things all day?" And actually, when I first joined as a tester, I had a bit of the same mentality. That’s why I wanted to find out for myself what testers actually do. I have worked at Microsoft for a year now as a tester on the Entity Framework team and have learned a lot about the discipline of test, but I know I have only scratched the surface. Also, I should clarify that these positions are opening on the runtime team, so you won’t be clicking on things that much, if at all. :)

My background as a .NET developer has really helped me excel as a test engineer. The challenges that we face are very diverse and as a result I think there are many more opportunities for growth in the test discipline than in other disciplines. In a sense, we are developers ourselves; we don’t ship code (typically), but we must have the ingenuity and creativity to verify the code that does ship meets a high quality bar. Test can be a very demanding discipline, especially for those people who have a background in development.

If you want to know more about my experiences feel free to contact me using the contact form page, and I hope you consider applying if you’re looking for a challenging job.

P.S. I should note that the Astoria job description is missing an important sales pitch—you get to work with Pablo Castro! Yes, that Pablo.

Posted by David DeWinter under Entity Framework | No Comments »

POCO Templates for Entity Framework v4 Beta 2 Released

January 25th 2010

Today we have finally released an update to the POCO Templates that is compatible with Visual Studio 2010 Beta 2. Official announcement on the ADO.NET team blog.

One thing I will highlight is that the templates won’t be released with the final version of Visual Studio 2010. Instead we will continue to push releases through the Visual Studio Extension Gallery. This means you can easily download the POCO Templates using Visual Studio’s Extension Manager (accessed through the Tools menu).

Extension Manager menu item

Once in the Extension Manager, click the Online Gallery tab on the left side of the window and use the search box (top right) to type in "POCO template." After a few seconds you should see the POCO template extensions appear. There are two extensions, one for C# and one for Visual Basic.

image

After you install the extension, you’ll have a new item template for C# projects or Visual Basic projects (depending on which you installed) that will allow you to generate POCO entities from an Entity Framework model. For more in depth information on how to use the POCO templates, have a look at the POCO Template Walkthrough.

As always we are interested in your feedback so feel free to request features or report bugs through the Microsoft Connect web site.

Posted by David DeWinter under .NET4/VS2010 & Entity Framework | No Comments »

LINQ Expression Trees and the Specification Pattern

May 31st 2009

Over the past couple of months I have tried to immerse myself in domain-driven design, which includes learning about its purpose, the methodology, and the domain patterns presented in Evans’ book and built upon in many other venues (blogs, conferences, etc.). While I have not worked on a full-fledged DDD project, I have fiddled with a lot of patterns. One of these is the Specification pattern, which says to introduce a predicate-like Value Object into the domain layer whose purpose is to evaluate whether an object meets some criteria. From what I’ve read in Evans’ book, specification objects typically have an isSatisfiedBy method that takes a domain object and returns a boolean. The specification therefore encapsulates a predicate that can be used to test an object to see if it satisfies the criteria.

image

The problem that Evans later calls out is that of querying a data store using specification objects as filters. Because using the specification to filter records from the database requires that those records be selected and reconstituted into objects, it can be inefficient for some applications to use specification objects as is. (Imagine using a specification object on one million rows in the Customer table just to find the gold Customers!) Surely we can do better.

Ideas

One idea in the book is to allow a repository to help with the implementation and utilize double dispatch to keep the separation of domain and infrastructure in tact. Application code calls a method on a repository to query for objects based on a specification. That repository passes itself to a method on the specification object, so the specification can utilize the repository’s power to query for the objects that fulfill the criteria, and then return that data to the application.

image

Another alternative is to harness the power of LINQ and expression trees to represent the predicate that the specification object encapsulates. This means that we can (1) use the expression trees in the infrastructure to let the data store take care of filtering and (2) still represent our rule in one location without resorting to compromises in the repository API.

Expression trees are abstract syntax trees that can represent the predicates that specification objects strive to encapsulate. With these expression trees, certain O/R mappers like LINQ to SQL, the Entity Framework, and LLBLGen Pro can determine the intent of the code and translate it into the corresponding T-SQL code to run against the database.

Creating an expression tree is very simple. In fact, if you’ve used any of the O/R mappers I mentioned above, you’ve probably used them already. Here’s an example of an expression tree being used in LINQ to SQL to generate the WHERE clause in the corresponding T-SQL query below.

NorthwindDataContext db = new NorthwindDataContext();

db.Products.Single(p => p.ProductName == "Aniseed Syrup");

SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]

FROM [dbo].[Products] AS [t0]

WHERE [t0].[ProductName] = @p0

– @p0: Input NVarChar (Size = 13; Prec = 0; Scale = 0) [Aniseed Syrup]

– Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1

Normally the lambda expression ‘p => p.ProductName == "Aniseed Syrup"’ would be treated as a Func<Product, bool>. However, in this particular usage the compiler infers that it is an Expression<Func<Product, bool>>. The difference means that the LINQ to SQL library no longer has a method pointer. Instead, it has a tree which represents what that method does. LINQ to SQL can visit the nodes in this tree and translate what it finds into SQL without ever invoking the code itself. A simple Func does not have that capability; it is simply a method pointer, like any other delegate type.

I hope you start to see how expression trees and the specification pattern can be very powerful together. If in addition to exposing an isSatisfiedBy method on the specification object, we add something which exposes the raw Expression, the repository can compose this Expression into the query and filter the results using the infrastructure. Let’s look at some code.

For this example, let’s continue to use the Products table from Northwind. The specification we implement here will tell us whether a product is a low stock product i.e. whether the number of units in stock for a particular product falls below a certain threshold. That threshold is defined in another system, so we will feed that data to the specification.

Let’s start with the basics. Here’s the base class for all Specifications. Instead of using IsSatisfiedBy, we expose a method which returns an expression tree of type Expression<Func<T, bool>>.

public abstract class Specification<T>

{

    public abstract Expression<Func<T, bool>> IsSatisfied();

}

The Expression class is in the System.Linq.Expressions namespace which is a part of System.Core.dll. Remember, this is just a different representation of IsSatisfiedBy; instead of keeping the logic embedded in a method in the specification object, we package the logic in an expression tree. The predicate still receives an object and returns a boolean. Other classes, like the ProductRepository, can now leverage this expression tree to optimize the query it sends to the database.

public partial class ProductRepository : IProductRepository

{

    public IQueryable<Product> SelectSatisfying(Specification<Product> specification)

    {

        return this.context.Products.Where(specification.IsSatisfied());

    }

}

Here we use the Entity Framework to select the Products that match a certain Product Specification. (The field "context" is the ObjectContext, in this case.) However, we could switch this for any data access technology that can leverage expression trees and retrieve similar results.

The next step is to implement the actual specification.

public class LowStockSpecification : Specification<Product>

{

    public LowStockSpecification(int lowStockThreshold)

    {

        this.LowStockThreshold = lowStockThreshold;

    }

 

    public int LowStockThreshold

    {

        get;

        private set;

    }

 

    public override Expression<Func<Product, bool>> IsSatisfied()

    {

        return p => p.UnitsInStock < this.LowStockThreshold;

    }

}

Evans says that specifications should be value objects, so I’ve taken that to heart and made this class immutable. This allows us to make some optimizations with specifications (caching the expression tree, introducing an IsSatisfiedBy by reusing the logic in the expression tree, etc.) if we would like.

This final code snippet shows how to leverage the specification and repository together.

public class ProductReorderingService

{

    private IProductRepository productRepository;

 

    public ProductReorderingService(IProductRepository productRepository)

    {

        this.productRepository = productRepository;

    }

 

    public void ReorderLowStockProducts()

    {

        LowStockSpecification spec = new LowStockSpecification(5);

        foreach (var p in this.productRepository.SelectSatisfying(spec))

        {

            // Reorder product

        }

    }

}

Composing Specifications

One property of specifications is that they can be combined to form more interesting predicates. This would allow our ProductRepository to support queries that involve multiple specification instances—for example, a filter that checks for units with low stock OR units whose stock is below their re-order level. The most common implementation I’ve seen of this requirement involves three new classes, AndSpecification<T>, OrSpecification<T>, and NotSpecification<T>. While it’s easy enough to implement these when all you worry about is IsSatisfiedBy (e.g. spec1.IsSatisfiedBy(o) && spec2.IsSatisfiedBy(o) for the AndSpecification<T>), it’s actually a bit tricky to do this with expressions.

Fortunately, it’s not impossible, and Colin Meek has it documented on his blog post about combining predicates in the Entity Framework, but the concepts apply more generally to any provider that can use expression trees. Be careful though; if you’re using the Entity Framework you will have to copy more code than you would with LINQ to SQL. I am not sure about LLBLGen Pro.

If you use the extension methods that Colin provides for AND’ing and OR’ing expression trees together, you’ll end up with these implementations of AndSpecification<T> and OrSpecification<T>:

public class AndSpecification<T> : Specification<T>

{

    private Specification<T> spec1;

    private Specification<T> spec2;

 

    public AndSpecification(Specification<T> spec1, Specification<T> spec2)

    {

        this.spec1 = spec1;

        this.spec2 = spec2;

    }

 

    public override Expression<Func<T, bool>> IsSatisfied()

    {

        return this.spec1.IsSatisfied().And(this.spec2.IsSatisfied());

    }

}

public class OrSpecification<T> : Specification<T>

{

    private Specification<T> spec1;

    private Specification<T> spec2;

 

    public OrSpecification(Specification<T> spec1, Specification<T> spec2)

    {

        this.spec1 = spec1;

        this.spec2 = spec2;

    }

 

    public override Expression<Func<T, bool>> IsSatisfied()

    {

        return this.spec1.IsSatisfied().Or(this.spec2.IsSatisfied());

    }

}

We’ll have to write the NotSpecification<T> ourselves, but this is not as involved as And and Or, even with the Entity Framework. We essentially take the body of the expression tree from the original specification and negate the result. Using the patterns you can read about in Colin’s blog post, we can use the following class as our NotSpecification<T>.

public class NotSpecification<T> : Specification<T>

{

    private Specification<T> originalSpec;

 

    public NotSpecification(Specification<T> originalSpec)

    {

        this.originalSpec = originalSpec;

    }

 

    public override Expression<Func<T, bool>> IsSatisfied()

    {

        Expression<Func<T, bool>> originalTree = this.originalSpec.IsSatisfied();

        return Expression.Lambda<Func<T, bool>>(

            Expression.Not(originalTree.Body),

            originalTree.Parameters.Single()

        );

    }

}

This is all well and good, but doesn’t this tie my domain to my infrastructure?

I think you can find arguments for both viewpoints. The specification pattern allows you to encapsulate a predicate to determine whether an object matches a condition. My opinion is whether that predicate is exposed as a method or an expression tree, the intent is preserved and there is one place where the criteria for a specification are checked. It does require you to use infrastructure that can utilize expression trees, but I would say that there is nothing about expression trees that tie them to the infrastructure layer directly. The details of the underlying data store have not leaked into the domain layer. If I had a provider that could use expression trees for XML or an object database store, then my domain layer would not change.

I enjoy learning about DDD and what other folks have done in this area. I’d love to hear your feedback.

Posted by David DeWinter under Design & Entity Framework & LINQ to SQL | 10 Comments »

Using LINQ to SQL and EF in Sharepoint under Medium Trust

April 22nd 2009

Code Access Security (CAS) is a large area of the .NET Framework that doesn’t often get the developer attention it deserves—at least, until it causes problems. Very recently I fielded a question on why the Entity Framework throws a SecurityException when executing a query in a Sharepoint-hosted web site run under medium trust. The answer, I thought, is definitely worth sharing.

The Repro

The failure looks very similar to the exception described on this forum post. However, the forum post describes a SecurityException thrown from an XBAP application, not an ASP.NET application. The reason for the failure, however, is the same. Take the following EF query, for example:

var customer = (from c in db.Customers

               where c.CustomerID == "ALFKA"

               select c).FirstOrDefault();

It’s a very simple query, which runs in medium trust without any errors. But consider the more useful use case:

public Customer GetCustomerById(string customerId)

{

    using (NorthwindEntities db = new NorthwindEntities())

    {

        return (from c in db.Customers

                where c.CustomerID == customerId

                select c).FirstOrDefault();

    }

}

The fundamental difference is that we’re using a parameter value to supply the criterion for our query. This throws the following exception in Sharepoint under medium trust:

System.MethodAccessException was unhandled by user code
  Message="System.Runtime.CompilerServices.StrongBox`1..ctor(System.__Canon)"
  Source="mscorlib"
  StackTrace:
       at System.Reflection.MethodBase.PerformSecurityCheck(Object obj, RuntimeMethodHandle method, IntPtr parent, UInt32 invocationFlags)
       at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
       at System.Linq.Expressions.ExpressionCompiler.AddGlobal(Type type, Object value)
       at System.Linq.Expressions.ExpressionCompiler.GenerateConstant(ILGenerator gen, Type type, Object value, StackType ask)
       at System.Linq.Expressions.ExpressionCompiler.Generate(ILGenerator gen, Expression node, StackType ask)
       at System.Linq.Expressions.ExpressionCompiler.GenerateMemberAccess(ILGenerator gen, Expression expression, MemberInfo member, StackType ask)
       at System.Linq.Expressions.ExpressionCompiler.Generate(ILGenerator gen, Expression node, StackType ask)
       at System.Linq.Expressions.ExpressionCompiler.GenerateLambda(LambdaExpression lambda)
       at System.Linq.Expressions.ExpressionCompiler.CompileDynamicLambda(LambdaExpression lambda)
       at System.Linq.Expressions.ExpressionCompiler.Compile(LambdaExpression lambda)
       at System.Linq.Expressions.ExpressionCompiler.Compile[D](Expression`1 lambda)
       at System.Linq.EnumerableExecutor`1.Execute()
       at System.Linq.EnumerableExecutor`1.ExecuteBoxed()
       at System.Data.Objects.ELinq.ClosureBinding.ParameterBinding.EvaluateBinding()
       at System.Data.Objects.ELinq.ClosureBinding.TryCreateClosureBinding(Expression expression, ClrPerspective perspective, Boolean allowLambda, HashSet`1 closureCandidates, ClosureBinding& binding, TypeUsage& typeUsage)
       at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
       at System.Data.Objects.ELinq.ExpressionConverter.EqualsTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression linq)
       at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
       at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
       at System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input)
       at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, DbExpression& source, DbExpressionBinding& sourceBinding, DbExpression& lambda)
       at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
       at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
       at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
       at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
       at System.Data.Objects.ELinq.ExpressionConverter.Convert()
       at System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
       at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)

  InnerException: System.Security.SecurityException
       Message="Request for the permission of type ‘System.Security.Permissions.ReflectionPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′ failed."
       Source="mscorlib"
       StackTrace:
            at System.Security.CodeAccessSecurityEngine.ThrowSecurityException(Assembly asm, PermissionSet granted, PermissionSet refused, RuntimeMethodHandle rmh, SecurityAction action, Object demand, IPermission permThatFailed)
            at System.Security.CodeAccessSecurityEngine.CheckSetHelper(PermissionSet grants, PermissionSet refused, PermissionSet demands, RuntimeMethodHandle rmh, Object assemblyOrString, SecurityAction action, Boolean throwException)
            at System.Security.PermissionSetTriple.CheckSetDemand(PermissionSet demandSet, PermissionSet& alteredDemandset, RuntimeMethodHandle rmh)
            at System.Security.PermissionListSet.CheckSetDemand(PermissionSet pset, RuntimeMethodHandle rmh)
            at System.Security.PermissionListSet.DemandFlagsOrGrantSet(Int32 flags, PermissionSet grantSet)
            at System.Security.CodeAccessSecurityEngine.ReflectionTargetDemandHelper(Int32 permission, PermissionSet targetGrant, CompressedStack securityContext)
            at System.Security.CodeAccessSecurityEngine.ReflectionTargetDemandHelper(Int32 permission, PermissionSet targetGrant)
       InnerException:

A Closer Look

The bolded text clues us into the real problem—a demand for ReflectionPermission failed. But we’re not doing reflection…or are we?

In order for our C# code to access the value of the customerId parameter, the compiler creates a new private nested class with a single public field for the customerId. When creating the expression tree to represent the query above, the compiler inserts code to instantiate this new class and adds that instance as a node in the tree. When the Entity Framework later processes the expression tree, it attempts to create an instance of that private class. (See above—RuntimeConstructorInfo.Invoke)

So what does permissions does this call to RuntimeConstructorInfo.Invoke require? In .NET 3.5, the demand is satisfied when all assemblies in the stack trace have one of the following sets of permissions:

  1. ReflectionPermission with ReflectionPermissionFlag.MemberAccess
  2. ReflectionPermission with ReflectionPermissionFlag.RestrictedMemberAccess UNION PermissionSet of the assembly which contains the member being reflected.

In .NET 2.0, ASP.NET medium trust did not allow reflection on non-public members. When Microsoft released .NET 3.5, the ReflectionPermission featured a new option: RestrictedMemberAccess (RMA). The concept is a bit tricky to understand the first time, so here’s an example of what RMA really means.

Take two assemblies, A and B. Assembly A is loaded in medium trust, and Assembly B is loaded in medium trust. Because both assemblies have the same trust level and because medium trust grants RMA, Assembly A can use reflection to discover non-public members in Assembly B. If a new assembly, Assembly C, is loaded in full trust, then Assembly A cannot use reflection to discover non-public members in Assembly C. If Assembly A is granted ReflectionPermission with MemberAccess, then it can use reflection on any assembly to discover any non-public member. Shawn Farkas discusses RMA in more detail here.

Assuming all this makes sense, let’s return to the problem. Our assembly is loaded in medium trust, and the code tries to reflect into the same assembly to find this non-public type generated by the compiler. However, the demand for ReflectionPermission still fails. This doesn’t make sense; the assembly’s permission set is equal to itself, and medium trust grants RMA…

The Solution

The key here is that medium trust in Sharepoint is not what we expect. The web.config file for our application points us in the right direction:

<trust level="WSS_Medium" originUrl="" />

The WSS_Medium trust level is not the same as the medium trust level offered by ASP.NET. On further investigation in the same web.config file, we see that WSS_Medium is defined in an external policy file:

<trustLevel

  name="WSS_Medium"

  policyFile="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\config\wss_mediumtrust.config" />

If you open the policy file, you’ll see this scavenger hunt leads us to one conclusion: Sharepoint medium trust does not include ReflectionPermission with RestrictedMemberAccess. To add this permission, you’ll need to make two changes to the policy file. First, add the following SecurityClass element to the configuration/mscorlib/security/policy/PolicyLevel/SecurityClasses element.

<SecurityClass

  Name="ReflectionPermission"

  Description="System.Security.Permissions.ReflectionPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

Second, add the RMA permission to the configuration/mscorlib/security/policy/PolicyLevel/NamedPermissionSets/PermissionSet[@Name='SPRestricted'] element. It should be the only one with child elements.

<IPermission

  class="ReflectionPermission"

  version="1"

  Flags="RestrictedMemberAccess"/>

Once the application pool is recycled, the CLR will grant you the RMA permission, and you will be able to run LINQ to SQL and EF queries like those shown above without any fear of SecurityExceptions.

Posted by David DeWinter under Entity Framework & LINQ to SQL | 2 Comments »

Data Access Confusion/Pain

March 29th 2009

I recently had an idea to retarget my blogging efforts to address confusing/little-known scenarios and pain points with LINQ to SQL and the Entity Framework. Since I’m using these technologies just about all the time now I have noticed that there is no end to the amount of discussion they bring up—from high-level architectural concerns like supporting n-tier and IoC to low-level implementation-specific questions like how to use the Attach family of methods in both technologies.

I’m going to prioritize my posts based on feedback I get personally (from here and other sources) and what I see on Twitter; KristoferA challenged twitterers (is that right?) to tweet their pains with both technologies with #linqtosqlpain and #efpain. I certainly have a few of my own that I want to address too.

(And yes, I have joined Twitter, too!)

Posted by David DeWinter under Entity Framework & LINQ to SQL | No Comments »

Entity Framework Tutorial Excerpt

December 21st 2008

Joydip Kanjilal has recently released a book all about the ADO.NET Entity Framework entitled Entity Framework Tutorial. In this book, Kanjilal explains and demonstrates the various features of EF, including how to create an Entity Data Model (EDM), using E-SQL and LINQ to Entities to perform queries, and even an introduction to ADO.NET Data Services (Astoria). Packt Publishing has provided me with an excerpt from this book where Kanjilal goes through building an EDM, which you may find below.

You may also be interested in a review that John Kilgo has written about Entity Framework Tutorial located here. Finally, scripts and code downloads for this book are available here. (You will have to provide your email address.)

Continue Reading »

Posted by David DeWinter under Entity Framework | No Comments »

Entity Framework Stored Procedure Generation

April 26th 2008

At work my team and I are utilizing the ADO.NET Entity Framework as a means to mitigate the object-relational impedance mismatch. Simply put, we’re utilizing it as an object-relational mapper for our latest project. So far we have been really impressed with the flexibility it provides us, especially surrounding the area of mapping the same table to multiple entity types and creating inheritance relationships among those entity types. It has proven itself as a much more viable candidate than .netTiers or LINQ to SQL for us.

While I have a lot of praise for the Entity Framework, there are some quirks that take getting used to. For example, you can’t update properties that are part of a primary key, even though you can update (non-identity) columns that are part of the primary key in SQL Server 2005. Another is the requirement that if an entity will be inserted into the database using a stored procedure, it must also be updated and deleted through a stored procedure. Yet another is that each stored procedure mapped to a particular entity type must have parameters mapped to every association key, regardless of the type of stored procedure (INSERT, UPDATE, or DELETE). For example, consider the following model:

image 

If I created stored procedures for the Account entity to use in my EF model, they’d look like this:

CREATE PROC dbo.Account_Insert

(

    @customerId INT

)

AS

BEGIN

    INSERT INTO Account (customerId)

    VALUES (@customerId)

 

    SELECT SCOPE_IDENTITY() as accountId

END

GO

 

CREATE PROC dbo.Account_Update

(

    @accountId INT,

    @customerId INT

)

AS

BEGIN

    UPDATE Account

    SET customerId = @customerId

    WHERE accountId = @accountId

END

 

CREATE PROC dbo.Account_Delete

(

    @accountId INT,

    @customerId INT

)

AS

BEGIN

    DELETE FROM Account

    WHERE accountId = @accountId

END

Notice the delete stored procedure—it must take in both the ID of the Account and the ID of the Customer it is associated with. Based on Colin Meek’s post here, I can understand why this is necessitated by the Entity Framework, but I can’t dispute the fact that it is different from I’m used to writing stored procedures.

As we moved towards implementing sprocs for our persistence layer to utilize, we ran into a few problems. At first, we thought we could utilize old templates from CodeSmith and .netTiers to generate sprocs, and our EF model would consume them gracefully. Unfortunately, if we used these templates, we would end up with sprocs like this for the Account table:

CREATE PROC dbo.Account_Insert

(

    @accountId INT OUTPUT,

    @customerId INT

)

AS

BEGIN

    INSERT INTO Account (customerId)

    VALUES (@customerId)

 

    SET @accountId = SCOPE_IDENTITY()

END

GO

 

CREATE PROC dbo.Account_Update

(

    @accountId INT,

    @customerId INT

)

AS

BEGIN

    UPDATE Account

    SET customerId = @customerId

    WHERE accountId = @accountId

END

 

CREATE PROC dbo.Account_Delete

(

    @accountId INT

)

AS

BEGIN

    DELETE FROM Account

    WHERE accountId = @accountId

END

Notice the slight differences:

  1. The INSERT sproc takes in an output parameter for the identity column and then sets the value of that parameter to the ID that was just inserted. The EF version of the sproc does not take in an output parameter; instead it just selects SCOPE_IDENTITY() for the EF to merge back into the Account entity that was inserted.
  2. The DELETE sproc does not take the parameter for the Customer ID, because it is not part of the primary key.

This causes some vexation for us because our new business domain houses about forty tables for which we need to write CUD sprocs that fit the Entity Framework’s rules. We could write them by hand (which would be painful and subject to error), try to modify CodeSmith’s templates to generate them correctly, or try to generate them using some other way.

From the title of this blog entry, you can probably infer that we didn’t write them by hand. Furthermore, Ryan Hauert and I were toying around with the idea of using T4 Templates to generate the SQL we needed. In all honesty, we didn’t even consider modifying the CodeSmith templates; I don’t think this was a bad choice, as T4 templates can benefit people who don’t want to purchase CodeSmith, but it may’ve been easier for our particular situation. But I digress…

The T4 template we created is designed to be a general purpose way to generate CUD procedures for an Entity Framework model. In case you didn’t read the links I provided on the templates, they are code-generation files which are intrinsically recognized by Visual Studio 2008. (They required the VS SDK in VS2005.) They have a .tt extension, and Visual Studio will nested generated code files underneath them in the Solution Explorer, similar to how designer files are nested under Entity Framework and LINQ to SQL models.

image

It’s a very simple process to use the T4 template:

  1. Add the file into your project. (The file is linked at the end of the blog entry.)
  2. Simply save the template file and CUD sprocs will be generated for every EDMX file in the current directory.

If you want to change what directory the template looks in or what files it generates sprocs for, look at the configuration parameters on lines 24 and 25 in the picture above. You can specify the directory explicitly by initializing the directoryName variable to anything other than the empty string or null. Furthermore, if you want to match a specific EDMX file only, you can use a regular expression to filter out unwanted files. I could use it like this:

Regex edmxFileFilter = new Regex(@"Entities\.edmx");

Then only the Entities.edmx file would be processed.

The template not only generates EF-compliant sprocs, but it also considers only the tables that are in the SSDL of the model file. Unfortunately, the template must query the database (SQL Server 2005 only!) in order to make all the decisions necessary to create the output file. However, this is usually quite fast on generations other than the first one.

As you can see from the picture above, the template requires a few different assemblies to be installed. Most of them shouldn’t be a problem when generating EF sprocs, because it strongly suggests that you have the .NET Framework 3.5 installed. Something you may not have are the SQL Server Server Management Objects (SMO), which offer an abstraction layer over the metadata of a SQL Server instance (e.g. databases, tables, columns, keys, indexes, data types), and keep the template cleaner than if we had to make ad hoc queries directly. The SMO installation is available on this page, where its installer is called "SQLServer2005_XMO.msi." There are other installers for 64-bit and Itanium 64-bit.

Once that is installed the template is very simple to run and gives us output like this:

image

Now we can take this script and run it against SQL Server and then import the sprocs into our Entity Framework model. Finally we can map the stored procedures to the entity types they encapsulate and voilà! We’re done.

There are a few limitations with the template the moment, but it will account for most cases:

  1. No stored procedures are generated for tables that do not have primary keys (in the database, not in the EF model). There is no way we can infer what you meant for the key to be for the update and delete sprocs; while we could generate insert procedures, it wouldn’t help the end user because the EF requires that an entity type be mapped to all three, or none at all.
  2. The template is available only in C# at the moment.
  3. It has not been tested in all scenarios, so any feedback you have would be great. :)
  4. It does not account for entity inheritance.

Download T4 Template

Special thanks to Bob Pace for giving Ryan and me the idea and providing helpful resources on T4.

Also, if you want to get started writing your own T4 templates, check out Hilton Giesenow’s excellent video here.

May 22, 2008 – Updates:

Ryan and I ran into an issue recently where we were accidentally comparing all of the parameters against values in database rows for the delete stored procedures. This was a mistake, because we really only need to check for equality on the primary key columns. The new template has been uploaded.

Posted by David DeWinter under Entity Framework & SQL Server | 38 Comments »