66

This code:

using (EntityConnection conn = new EntityConnection("name=ELSCommonEntities"))
{
  conn.Open();
}

Gives me the following error:

Test method ELS.Service.Business.IntegrationTest.Base.ServiceBaseIntegrationTest.StartLoggingTestMethod threw exception:  System.Data.MetadataException: Unable to load the specified metadata resource..

With the following stack trace:

System.Data.Metadata.Edm.MetadataArtifactLoaderCompositeResource.LoadResources(String assemblyName, String resourceName, ICollection`1 uriRegistry, MetadataArtifactAssemblyResolver resolver)
System.Data.Metadata.Edm.MetadataArtifactLoaderCompositeResource.CreateResourceLoader(String path, ExtensionCheck extensionCheck, String validExtension, ICollection`1 uriRegistry, MetadataArtifactAssemblyResolver resolver)
System.Data.Metadata.Edm.MetadataArtifactLoader.Create(String path, ExtensionCheck extensionCheck, String validExtension, ICollection`1 uriRegistry, MetadataArtifactAssemblyResolver resolver)
System.Data.EntityClient.EntityConnection.SplitPaths(String paths)
System.Data.EntityClient.EntityConnection.GetMetadataWorkspace(Boolean initializeAllCollections)
System.Data.EntityClient.EntityConnection.InitializeMetadata(DbConnection newConnection, DbConnection originalConnection, Boolean closeOriginalConnectionOnFailure)
System.Data.EntityClient.EntityConnection.Open()
ELS.Service.Business.Base.ServiceBase.StartLogging(String userWindowsLogon) in C:\C-TOM\ELS-RELEASE1\ELS.Service.Business\Base\ServiceBase.cs: line 98
ELS.Service.Business.IntegrationTest.Base.ServiceBaseIntegrationTest.StartLoggingTestMethod() in C:\C-TOM\ELS-RELEASE1\ELS.Service.Business.IntegrationTest\Base\ServiceBaseIntegrationTest.cs: line 65

However, this code which uses the same connection string:

using (ELSCommonEntities db = new ELSCommonEntities())
{
    var res = from c in db.Logging
              select c;

    int i = res.Count();
}

Does not give an error.

The connection string is:

<add name="ELSCommonEntities" connectionString="metadata=res://*/Common.CommonModel.csdl|res://*/Common.CommonModel.ssdl|res://*/Common.CommonModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=localhost;Initial Catalog=els5_demo;Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />

I have also opened up the dll in reflector and the metadata looks ok.

Scott Weldon
  • 9,673
  • 6
  • 48
  • 67
Shiraz Bhaiji
  • 64,065
  • 34
  • 143
  • 252
  • 4
    Please, please, please, always post the complete exception, including stack trace and inner exceptions. Post the results of ex.ToString(). – John Saunders Jul 02 '09 at 13:41
  • 3
    I hope you don't mind. I edited your question to fix the format. You should indent with four spaces to format as code. Otherwise, select the code and press the button with the 10101. – John Saunders Jul 02 '09 at 13:57

8 Answers8

117

Found the problem.

The standard metadata string looks like this:

metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl

And this works fine in most cases. However, in some (including mine) Entity Framework get confused and does not know which dll to look in. Therefore, change the metadata string to:

metadata=res://nameOfDll/Model.csdl|res://nameOfDll/Model.ssdl|res://nameOfDll/Model.msl

And it will work. It was this link that got me on the right track:

http://itstu.blogspot.com/2008/07/to-load-specified-metadata-resource.html

Although I had the oposite problem, did not work in unit test, but worked in service.

Markus Jarderot
  • 86,735
  • 21
  • 136
  • 138
Shiraz Bhaiji
  • 64,065
  • 34
  • 143
  • 252
  • 4
    "Some cases" are when you have more than one edmx file with same name (Model1 for example). – alpav Feb 16 '10 at 17:17
  • 1
    My "some case" was with only one .edmx file in the solution. I have no idea what happened, but it was horrible. ;) – John Farrell Feb 16 '10 at 19:33
  • 3
    The link you gave led me to the answer, so you are getting my upvote! I fought with this for half a day. I had tried res://NameOfDLL/... but with no success. However, I finally got it to work with res://NameOfAssembly/... In this case, they were the same name except the assembly name didn't have .dll on the end. – Kasey Speakman Nov 04 '10 at 00:50
  • 3
    I changed the namespace of my Model after I generated the connection string, after I fixed the connection string per your instruction and it worked fine. – Ryan Eastabrook Mar 18 '11 at 23:29
  • Said to myself - If this work I'll upvote him. So there you go! Thx for the help! – peterthegreat Apr 13 '11 at 19:43
  • 3
    I'm up-voting because this solved my issue. Thanks! – l15a Jul 18 '12 at 19:04
  • Solved my issue with this EF error "Schema specified is not valid. Errors: error 0194: All artifacts loaded into an ItemCollection must have the same version. Multiple versions were encountered." – nemke Jan 20 '14 at 15:04
  • Old post, but just a quick comment about unit testing. I had made a change to the name of my EDMX model, but had forgotten about the connection string in the Test projects app.config. – Jazzy Jun 22 '16 at 14:28
  • Encountered this problem because I renamed my .edmx and the model - the old EF in my project was so different - I decided to delete and re-create my .edmx and update from database. I had to fix the one line in web.config under the group and fix the names in the element for attribute connectionString= the 3 places where the name was wrong was obvious - so I was able to spot the name difference quickly. – qxotk Jun 30 '16 at 18:40
  • its working after update the dll name instead of "*" , Thank you so much @Shiraz Bhaiji – sankar ganesh Oct 30 '19 at 06:46
45

I had the same error message, and the problem was also the metadata part of the connection string, but I had to dig a little deeper to solve it and wanted to share this little nugget:

The metadata string is made up of three sections that each look like this:

res://
      (assembly)/
      (model name).(ext)

Where ext is "csdl", "ssdl", and "msl".

For most people, assembly can probably be "*", which seems to indicate that all loaded assemblies will be searched (I haven't done a huge amount of testing of this). This part wasn't an issue for me, so I can't comment on whether you need the assembly name or file name (i.e., with or without ".dll"), though I have seen both suggested.

The model name part should be the name and namespace of your .edmx file, relative to your assembly. So if you have a My.DataAccess assembly and you create DataModels.edmx in a Models folder, its full name is My.DataAccess.Models.DataModels. In this case, you would have "Models.DataModels.(ext)" in your metadata.

If you ever move or rename your .edmx file, you will need to update your metadata string manually (in my experience), and remembering to change the relative namespace will save a few headaches.

Ian Yates
  • 921
  • 8
  • 15
  • 8
    THANK YOU! There are 100 answers for this available on the internet, but this is the the most helpful addendum to any of them. A clear example: In `DalProject.dll` you have a folder `Client` which has the `Client.edmx` file in it. So you then replace `//*/Client.(csdl/ssdl/msl)` with `//DalProject/Client.Client.(csdl/ssdl/msl)` – Maverick Dec 03 '13 at 00:08
  • It seems "My.DataAccess." is not required; only the "Models.DataModels" part (perhaps it works relative to each assembly root namespace searched). – James Wilkins May 21 '16 at 04:11
14

There are several possible catches. I think that the most common error is in this part of the connection string:

res://xxx/yyy.csdl|res://xxx/yyy.ssdl|res://xxx/yyy.msl;

This is no magic. Once you understand what is stands for you'll get the connection string right.

First the xxx part. That's nothing else than an assembly name where you defined you EF context clas. Usually it would be something like MyProject.Data. Default value is * which stands for all loaded assemblies. It's always better to specify a particular assembly name.

Now the yyy part. That's a resource name in the xxx assembly. It will usually be something like a relative path to your .edmx file with dots instead of slashes. E.g. Models/Catalog - Models.Catalog The easiest way to get the correct string for your application is to build the xxx assembly. Then open the assembly dll file in a text editor (I prefer the Total Commander's default viewer) and search for ".csdl". Usually there won't be more than 1 occurence of that string.

Your final EF connection string may look like this:

res://MyProject.Data/Models.Catalog.DataContext.csdl|res://MyProject.Data/Models.Catalog.DataContext.ssdl|res://MyProject.Data/Models.Catalog.DataContext.msl;

HANiS
  • 530
  • 5
  • 9
3

As Shiraz Bhaiji answered, the metadata=res:///Model.csdl|res:///Model.ssdl|res://*/Model.msl was the case. However I still had problems with constructing the proper string based on my Model localization, namespaces and assemby name. The very simple solution was to rename the .edmx file in Visual Studio(after than rename and get back to the original name), which triggered the automatic refreshing of the string in my Web.config

Paweł Forys
  • 347
  • 1
  • 3
  • 15
0

I had the same problem with three projects in one solution and all of the suggestions didn't work until I made a reference in the reference file of the web site project to the project where the edmx file sits.

Dov Miller
  • 1,958
  • 5
  • 34
  • 46
0

I moved my Database First DataModel to a different project midway through development. Poor planning (or lack there of) on my part.

Initially I had a solution with one project. Then I added another project to the solution and recreated my Database First DataModel from the Sql Server Dataase.

To fix the problem - MetadataException when using Entity Framework Entity Connection. I copied my the ConnectionString from the new Project Web.Config to the original project Web.Config. However, this occurred after I updated my all the references in the original project to new DataModel project.

stink
  • 865
  • 8
  • 19
0

It might just be a connection string error, which is solved by the above process, but if you are using the dll's in multiple projects then making sure the connection string is named properly will fix the error for sure.

ransems
  • 641
  • 7
  • 19
0

I had this problem when moving my .edmx database first model from one project to another.

I simply did the following:

  1. Deleted the connection strings in the app.config or web.config
  2. Deleted the 'Model.edmx'
  3. Re-added the model to the project.
Zapnologica
  • 22,170
  • 44
  • 158
  • 253