Troubleshooting Entity Framework Connection Strings

Posted by on in Blogs
In an application which uses the Entity Framework, you may see the following error at runtime:
MetadataException: Unable to load the specified metadata resource

The cause of this error is a missing or malformed Entity Framework connection string. In particular, the cause of this error is the metadata parameter of the connection string. Let's examine this more closely.

Which Config File?


Before you begin troubleshooting, make sure you are looking at the correct file.

Connection strings are loaded from the configuration file for the executing assembly, which may not be the assembly which contains your Entity Framework model. So if you have a data assembly containing an Entity Framework model and a web assembly containing a web application which references the data assembly, then the Entity Framework connection string needs to be in the Web.config file for the web assembly. The data assembly can have its own connection string, if you like (this is convenient, as it will be used by the Entity Framework designer), but it will not be used by the web application at runtime.

Metadata


MSDN documents EF connection strings generally. But the cause of the error above is specifically the metadata parameter. This parameter tells the Entity Framework where to find your EDMX at runtime. When your application is compiled, the EDMX is split into three parts: CSDL, MSL, and SSDL. For the purposes of this post, you don't need to think about what they mean right now; it's enough to know that you need all three of them at runtime.

The EDMX can be supplied to the application as embedded resources or files on disk. The default is embedded resources, so we'll focus on that case.

The metadata parameter for an application with an Entity Framework model called Model.edmx in an assembly called Simple Mvc.Data.dll might look like this:

<connectionStrings>
<add name="MyEntities" connectionString="metadata=
res://Simple Mvc.Data.dll/Model.csdl|
res://Simple Mvc.Data.dll/Model.ssdl|
res://Simple Mvc.Data.dll/Model.msl;provider= <!-- ... -->


So you can see there is one reference for each of the three parts of the EDMX that we need at runtime. They all work in the same way, so let's examine just the first more closely. The CSDL reference looks like this:
            res://Simple Mvc.Data.dll/Model.csdl

It specifies three things:

  1. We're loading the CSDL from a resource. That's the "res://" part.

  2. The name of the assembly which contains the resource, "Simple Mvc.Data.dll". If your assembly is strong named, you can specify a strong name, in all its verbose glory, here.

  3. The name of the resource itself, "Model.csdl". Do not confuse this with the EDMX or model name. In this case they happen to be the same, except for the extension, but that's not always true!


Let's examine #2 and 3 more closely.

Assembly name


It's really common to omit the assembly name in a connect string, and use * instead, like this:

<connectionStrings>
<add name="MyEntities" connectionString="metadata=
res://*/Model.csdl|
res://*/Model.ssdl|
res://*/Model.msl;provider= <!-- ... -->


This means that instead of loading the resource from one specific assembly, the EF will scan all loaded assemblies at runtime. Two obvious downsides to this are that it takes a bit of time to do this, and the assembly might not be loaded yet. The second case is one reason you might get the error at the start of this post. So specifying the assembly explicitly is always a good idea, I think.

Resource names


Remember how I said that the resource name isn't necessarily the same as the model name? Here's a real-life example of that. I opened one of our production assemblies in Reflector, and found this:



There's actually a good reason that those resources have such bizarre names, but it's a digression and not relevant to this post. The point is that after you're sure the assembly name is right, the next step in solving the error at the top of this post is to double-check the resource names.

A simpler resource name will look like this:



Remember the "simpler" metadata where I used * instead of the assembly name? You can go even simpler. This metadata, perhaps surprisingly, actually works (with caveats):

<connectionStrings>
<add name="MyEntities" connectionString="metadata=
res://*/;provider= <!-- ... -->


This is the "throw everything against the wall and see what sticks" approach to a connect string. It will probably fail if your resources don't happen to have the same name as your model, or if the assembly doesn't happen to be loaded. But it (in simpler cases, anyway) frees the programmer from having to think about what any of this stuff means, so it's a popular solution.

Comments

  • Guest
    Mauro Saturday, 21 August 2010

    Thanks, a good guide for that very non descriptive error.
    "Unable to load the specified metadata resource"

    Thanks agains

  • Guest
    Bryce Sunday, 05 September 2010

    This error was driving me up the wall. I think I have it fixed now. Some things I know so well and other items like this I'm lost

  • Guest
    Matthias Liebeck Saturday, 18 September 2010

    Nice post. You should work on your SEO to achieve a higher google ranking. I was unable to find this entry with google. Your link on stackoverflow brought me here

  • Guest
    Marius Mans Monday, 04 October 2010

    Greate, Greate, Great !!!! After 3 hours of searching, this is the solution that explains the problem. FIXED.

  • Guest
    Dean Wednesday, 17 November 2010

    You are a man among men! I couldn't get my test harness to work until your post made me realise my testing app.config was out of date. Thank you very much!

  • Guest
    Jamie Monday, 06 December 2010

    Great blog post - I was going crazy with this error. Very helpful indeed.

  • Guest
    John Thursday, 16 December 2010

    Wonderfully lucid ! Thank you !

  • Guest
    Narek Friday, 04 March 2011

    Thank you very much, great help!

  • Guest
    Brad Wednesday, 09 March 2011

    Any suggestions for getting a connection string to work for an OData service when the EF entities are in a second assembly? Using VS 2010 and .NET 4 I can make the service work when the entitites are declared in the web app offering the service but get the following error when attempting to access the service when entities are declared in a second project.

    "The server encountered an error processing the request. See server logs for more details."

    Unfortunately no logs when running out of VS. I've tried both the * and explicit assembly reference. One thing I haven't test yet is moving my entities to the root folder in the shared assembly. Currently they are in a subfolder in the project assembly and in their own namespace - Application.Project.EntitiesName.

  • Guest
    naspinski Friday, 25 March 2011

    First of all, GREAT post, this has been a great help. I think I am on the right track, everything works on my local machine and on my dev machine as long as I transfer the file manually. If I use Nant to build the files, I still get the evil error. Everything is still strongly named (checked with the 'sn -T' tool) and it looks identical, but will not work - I have the full names in the connectionstring and everything. I am not sure if you use Nant or not or maybe might know what else is going on, but any help right now would be appreciated! Thanks again.

  • Guest
    naspinski Monday, 28 March 2011

    You are right, Nant is not compiling the resources at all - they are just not there in reflector. At least I can narrow it down to figuring out how to get the resources and the signing to work together (can seem to get them both to work separately, but not together). Thanks again for the help! Do you happen to know anything about Nant and this problem? :)

  • Guest
    naspinski Monday, 28 March 2011

    You definitely got me on the right track, thank you so much!

  • Guest
    jp2code Tuesday, 24 May 2011

    How do I specify a Password parameter?

  • Guest
    mohaaron Friday, 27 May 2011

    What do I do when the Resources directory is missing when looking at the assembly in Reflector?

  • Guest
    Vinod Tuesday, 28 June 2011

    You have no idea how much this post helped me! Thanks a million!

  • Guest
    sam Monday, 11 July 2011

    Thanks. I was about to throw my laptop out of window. And going to fight with my wife. You saved both.

  • Guest
    codemonkey Wednesday, 13 July 2011

    I was getting:

    System.IO.FileNotFoundException : Unable to resolve assembly 'MyAssemblyName.dll'

    I found that i had to remove the ".dll" from the assembly name if I want to specify it explicitly in the connection string. Hope this helps anyone else with that problem.

    Great article, very clear on a potentially confusing topic!

  • Guest
    Zhirong Saturday, 03 September 2011

    Really helpful! I finally start running my code with your explanation. thank you:)

  • Guest
    nik shornikov Friday, 16 September 2011

    second the comment about SEO, but more importantly, I wish more people would slow down and share what they know

  • Guest
    AlexxxTremer Tuesday, 20 September 2011

    Thanks, this helps me a lot!

  • Please login first in order for you to submit comments