Executing a stored procedure in Entity Framework without Mapping

by David Kiff 23. March 2010 08:44

We had a requirement to call a stored procedure in order to insert some data into a table as part of the products setup.  My first impressions were great, this should be easy, I know Entity Framework supports stored procedures!

I was expecting to update my model, select the new stored procedure and Entity Framework would import it and create me a nice strongly typed method like so:

Stored procedure name: CreateProductDefaultsForSetup

Expected Entity Framework result: _context.CreateProductDefaultsForSetup(productId);

After importing the stored procedure I searched the generated file for the procedure name with no luck.  I searched online and found loads of posts explaining how it can be achieved when you want to map it back to an entity, which I did not!

Eventually I found out that I needed to write some code that looks like this:

public void Execute(string storedProcedureName, params KeyValuePair<string, object>[] arguments)
{
    using (EntityConnection connection = (EntityConnection)_context.Connection)
    {
        using (EntityCommand command = connection.CreateCommand())
        {
            command.CommandType = CommandType.StoredProcedure;
            command.CommandText = storedProcedureName;
            foreach (KeyValuePair<string, object> argument in arguments)
            {
                command.Parameters.AddWithValue(argument.Key, argument.Value);
            }
            connection.Open();
            command.ExecuteNonQuery();
            connection.Close();
        }
    }
}

I could then call the method like so:

Execute("Entities.CreateProductDefaultsForSetup", new KeyValuePair<string, object>("ProductID", productId));

Not quite as clean as I wanted!  Note that the command text is not just the name of the stored procedure.

After all this, it still didn’t work, giving me an error of:

“The FunctionImport CreateProductDefaultsForSetup could not be found in the container”

This took a while to fix with no documentation found online.  You need to right-click some whitespace in the Entity Framework designer and select Add > Function Import from the context menu, then follow the simple online prompt.

Finally I had my stored procedure being executed from Entity Framework, shame it wasn’t as straightforward as I have thought!

Tags:

Entity-Framework

Creating a WCF Operation Invoker to handle exceptions

by David Kiff 23. September 2009 15:25

I found myself repeating the same old try..catch logic within our WCF services.  Quite often we would catch specific exceptions and re-throw them as fault exceptions, whereas the rest required logging and re-throwing.

I decided to create a wrapper around the class responsible for invoking the operations.  That will allow us to add a generic try..catch around every operation, that we apply the behaviour to.More...

Tags: , ,

WCF

Setting up SSL for WCF in Development

by David Kiff 22. September 2009 11:27

This blog post will describe how to secure your WCF services that are hosted within IIS 7.0, using Secure Sockets Layer.

Secure Sockets Layer (SSL) is a protocol primarily used for encryption of data between two parties, running at the Transport Layer.More...

Tags: , , , ,

WCF

Unable to load one or more of the requested types

by David Kiff 21. September 2009 16:41

I have spent around 4 hours trying to diagnose the follow exception:

“Unable to load one or more of the requested types”

This error message is extremely unhelpful, so I took a look at the stack, that suggested that EntityFramework was causing the exception:

 

Retrieve the LoaderExceptions property for more information. at System.Reflection.Module._GetTypesInternal(StackCrawlMark& stackMark) at System.Reflection.Assembly.GetTypes() at System.Data.Metadata.Edm.ObjectItemCollection.AssemblyCacheEntry.LoadTypesFromAssembly(LoadingContext context) at System.Data.Metadata.Edm.ObjectItemCollection.AssemblyCacheEntry.InternalLoadAssemblyFromCache(LoadingContext context)

 

The stack has contains a helpful message that I overlooked in my haste to fix the problem “Retrieve the LoaderExceptions property for more information”. 

The next question is how do you retrieve “more information”?  Where is that property?  The answer lies within the ReflectionTypeLoadException, which contains the LoaderExceptions property (an array of helpful exceptions).

In the debugger it would have been easy to identify this, however this issue was appearing in our test environment with no debugging support.  I ended up adding a try and catch around the offending code (found from the original stack trace), then casting the exception to ReflectionTypeLoadException and persisting the message and stack trace to a file:

try
{
        //Do work
}

catch(Exception ex)
{         

             ReflectionTypeLoadException exception = ex as ReflectionTypeLoadException;

              if(exception == null)
                  System.IO.File.AppendAllText("C:\\TestLog.txt", "Not a ReflectionTypeLoadException ex.");
              else
              {
                  foreach (Exception loaderException in exception.LoaderExceptions)
                  {
                      System.IO.File.AppendAllText("C:\\TestLog.txt", loaderException.Message);
                      System.IO.File.AppendAllText("C:\\TestLog.txt", loaderException.StackTrace);
                  }
              }

}

Tags:

Do I need documents when Test Driving my Development?

by David Kiff 16. September 2009 08:00

I was talking to a friend not so long ago about documentation. My argument is that writing external documents in order to define the behaviour and interactions of software is (or should be) covered by the business/stakeholders in their requirements or with the acceptance tests that have been defined for the application. There is of course a need to document the technical details, such as why you did something the way you did, and I feel this is best covered from self describing, well written, Unit Tests. More...

Tags: , , ,

Test-Driven-Development

WCF Inversion of Control “Service Constructor” and better Unit Testing!

by David Kiff 28. August 2009 15:40

When creating a WCF service that is hosted in IIS using the .svc file, you need to specify the Service attribute in the directive.  The value of this service attribute is the fully qualified type name of service file (the one that contains the implementation of the service).  More...

Tags: , ,

WCF

EF Strongly Typed ObjectQuery<T>.Include(“”);

by David Kiff 27. August 2009 09:39

In my most recent project, I have been asked to use EntityFramework.  To decouple this from the rest of the system, I wanted to encapsulate its implementation behind a repository. 

By default the Entity Framework does not load the entire object graph into memory, nor does it load it on demand, for example, if you have an Order entity that has a number of OrderDetails, then the OrderDetails will not be present until you include it in the query like so:

 

using (CommuicationsEntities entities = new CommuicationsEntities()) 

    entities.Order.Include("OrderDetails")
}

This approach has the obvious flaw that it uses magic strings.  If you change your model and forget to change the property name, you wont receive an error until runtime.  It would also be great to leave it up to the repository client to decide how much of the object graph they need.  There is no point loading the entire graph into memory and only use a small part of it.

After some looking around I found a great post by Kim Major here.  This article explains an approach that I like, using an “IncludeBuilder” to build up the includes in a strongly type manor and passing them to the repository.  Unfortunately the post does not have any code samples, leaving me to work out how to write it.  This is the implementation I came up with:

 

public class IncludeBuilder<T>
{
    private readonly List<string> _propertiesToInclude;

    public IncludeBuilder()
    {
        _propertiesToInclude = new List<string>();
    }

    public void Add(Expression<Func<T, object>> propertySelector)
    {
        MemberExpression memberExpression = propertySelector.Body as MemberExpression;
        if (memberExpression == null)
            throw new ArgumentException("Parameter propertySelector must be a MemberExpression");
        _propertiesToInclude.Add(memberExpression.Member.Name);
    }

    public ObjectQuery<T> Includes(ObjectQuery<T> query)
    {
        foreach (string include in _propertiesToInclude)
        {
            query = query.Include(include);
        }
        return query;
    }
}

 

It took me a while to realise you need to re-assign the query back to the main query as soon as you have added the include:

query = query.Include(include);

Now the repository consumer can do the following:

IRepository<Order> repository = new OrderRepository(new FulfilmentEntities());

 

IncludeBuilder<Order> includeBuilder = new IncludeBuilder<Order>();
includeBuilder.Add(a=> a.OrderDetails);

Order alerts = repository.GetSingle(11);

 

The code within the repository can add the includes in the following way:

public Alert GetSingle(int orderId, IncludeBuilder<Order> includeBuilder)
{
      return includeBuilder.Includes(_entities.Orders).Select(a => a).First();
}

Hopefully this helps someone :)

Tags:

Entity-Framework

Unit Testing

by David Kiff 10. July 2009 19:58

Unit testing is the testing of a small isolated unit, typically a method. It is written to ensure the code behaves in the way it is intended, drives the architecture and ensures the code meets its requirements. More...

Tags:

Test-Driven-Development

Getting started with the TFS API (Get Latest App)

by David Kiff 2. July 2009 23:02

Introduction

I have been working for around two years within the In-store team for Tesco.com. Around three weeks ago, I was asked to help the web team deliver the customer’s favourite’s part of the new Tesco.com website, code named Martini.

After the first day when I performed a "get latest" and then on to a full build, I realised I needed some automation. More...

Tags:

TFS

Creating Lambda Extension Methods

by David Kiff 18. March 2009 20:08

There are lots of blogs on Extension Methods and Lambda Expressions; however I haven’t seen many blogs looking at combining the two! This is the aim of this Article. I will replicate the Where extension method for IEnumerable<T> to demonstrate an example. More...

Tags:

C#-3.0