MetadataException: Unable to load the specified metadata resource
A minor amendment helped me with this problem.
I had a solution with 3 project references:
connectionString="metadata=res://*/Model.Project.csdl|res://*/Model.Project.ssdl|res://*/Model.Project.msl;
which I changed to:
connectionString="metadata=res://*/;
I had a similar error. I had recreated the project (long story), and pulled everything over from the old project. I hadn't realized that my model had been in a directory called 'Model' before, and was now in a directory called 'Models'. Once I changed the connection in my Web.Config from this:
<add name="RecipeManagerEntities" connectionString="metadata=res://*/Model.Recipe.csdl
to this:
<add name="RecipeManagerEntities" connectionString="metadata=res://*/Models.Recipe.csdl
Everything worked (changed Model
to Models
). Note that I had to change this three places in this string.
You can get this exception when the Edmx is in one project and you are using it from another.
The reason is Res://*/
is a uri which points to resources in the CURRENT assembly. If the Edm is defined in a different assembly from the code which is using it, res://*/ is not going to work because the resource cannot be found.
Instead of specifying ‘*’, you need to provide the full name of the assembly instead (including public key token). Eg:
res://YourDataAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=abcdefabcedf/YourEdmxFileName.csdl|res://...
A better way to construct connection strings is with EntityConnectionStringBuilder:
public static string GetSqlCeConnectionString(string fileName)
{
var csBuilder = new EntityConnectionStringBuilder();
csBuilder.Provider = "System.Data.SqlServerCe.3.5";
csBuilder.ProviderConnectionString = string.Format("Data Source={0};", fileName);
csBuilder.Metadata = string.Format("res://{0}/YourEdmxFileName.csdl|res://{0}/YourEdmxFileName.ssdl|res://{0}/YourEdmxFileName.msl",
typeof(YourObjectContextType).Assembly.FullName);
return csBuilder.ToString();
}
public static string GetSqlConnectionString(string serverName, string databaseName)
{
SqlConnectionStringBuilder providerCs = new SqlConnectionStringBuilder();
providerCs.DataSource = serverName;
providerCs.InitialCatalog = databaseName;
providerCs.IntegratedSecurity = true;
var csBuilder = new EntityConnectionStringBuilder();
csBuilder.Provider = "System.Data.SqlClient";
csBuilder.ProviderConnectionString = providerCs.ToString();
csBuilder.Metadata = string.Format("res://{0}/YourEdmxFileName.csdl|res://{0}/YourEdmxFileName.ssdl|res://{0}/YourEdmxFileName.msl",
typeof(YourObjectContextType).Assembly.FullName);
return csBuilder.ToString();
}
If you still encounter the exception, open the assembly in reflector and check the filenames for your .csdl, .ssdl and .msl files. When the resources have different names to the ones specified in the metadata value, it’s not going to work.
This means that the application is unable to load the EDMX. There are several things which can cause this.
- You might have changed the MetadataArtifactProcessing property of the model to Copy to Output Directory.
- The connection string could be wrong. I know you say you haven't changed it, but if you have changed other things (say, the name of an assembly), it could still be wrong.
- You might be using a post-compile task to embed the EDMX in the assembly, which is no longer working for some reason.
In short, there is not really enough detail in your question to give an accurate answer, but hopefully these ideas should get you on the right track.
Update: I've written a blog post with more complete steps for troubleshooting.