views:

12479

answers:

19

All of a sudden I keep getting a MetadataException on instantiating my generated ObjectContext class. The connectionstring in App.Config looks correct - hasn't changed since last it worked - and I've tried regenerating a new model (edmx-file) from the underlying database with no change.

Anyone have any... ideas?

Edit: I haven't changed any properties, I haven't changed the name of any output assemblies, I haven't tried to embed the EDMX in the assembly. I've merely waited 10 hours from leaving work until I got back. And then it wasn't working anymore.

I've tried recreating the EDMX. I've tried recreating the project. I've even tried recreating the database, from scratch. No luck, whatsoever.

I'm truly stumped.

+29  A: 

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.

Craig Stuntz
The connectionstring, despite my efforts to compare it with a content-compare utility last time, *was* wrong.
J. Steen
It was the connectionstring for me too. When you have Integration Tests that also need connectionsting in its own App.config, things may go out of sync when you update your edmx.
ray247
+1  A: 

The ultimate solution (even after recreating the database on two other machines, as well as EDMX and other sundries) was to not use the horribly limited Entity Framework. Looking forward to evaluating it again in .NET 4.0.

EDIT:

After running into the same problem -again- and going all over teh googles for an answer, I finally found someone who'd had the same problem. It appears that the connectionstring wasn't correctly generated by Visual Studio's wizard, and the link to the metadata resources were missing an important path. Not completely bloody obvious, I tell you. =)

http://forums.asp.net/p/1409590/3082930.aspx

J. Steen
Hey, giving a reason for the downvote is always nice! =) This was my solution, and worked for me. Do you have a better one?
J. Steen
+26  A: 

This little change help with this problem.

I have Solution with 3 project.

connectionString="metadata=res:///Model.Project.csdl|res:///Model.Project.ssdl|res://*/Model.Project.msl;

change to

connectionString="metadata=res://*/;

MicTech
+1 for this solving my problem.
Russell Steen
This solution worked for me when I was having the same issue.
Jeremy Sullivan
Thank you thank you thank you. After tinkering with this for hours, your answer solved my problem.
JohnnyO
how do you know that? You are the hero.
5YrsLaterDBA
It fixed it for me, but what the heck does it mean?
Lance Fisher
@Lance: I explain this in detail in [this blog post](http://blogs.teamb.com/craigstuntz/2010/08/13/38628/)
Craig Stuntz
ThankYouThankYouThankYouThankYouThankYouThankYouThankYouThankYouThankYou
John Gietzen
A: 

I deleted the app.connection string and started over. app.config stuff delete. Then re-add the entity data model stuff, it should be fine.

You obviously didn't read my posts, where I said I recreated everything as far down as the database itself. =)
J. Steen
+1  A: 

I had the same problem. I just had a look into my complied dll with reflector and see that the name of the ressource where not the right ones. I renamed and look fines now

Pitming
+4  A: 

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. (Note that I had to change this three places in this string.

Rick Arthur
A: 

This happened to me when I accidentally switched the Build Action of the edmx file (appears under Properties in the IDE) from 'EntityDeploy' to 'None'. EntityDeploy is what populates the metadata for you: see http://msdn.microsoft.com/en-us/library/cc982037.aspx

fool_on_the_hill
+1  A: 

I've just spent a happy 30 minutes with this. I'd renamed the entities object, renamed the entry in the config file, but there's more ... you have to change the reference to the csdl as well

very easy to miss - if you're renaming, make sure you get everything ....

TobyEvans
A: 
eagle779
A: 

My theory is that if you have more than one edmx file with same name (Model1 for example), it will give that exception. I've got same problem when I decided to name all my edmx files (sitting in different projects) as Model1 because I thought they should be independent.

alpav
+12  A: 

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.

thx so much for this tip!
frabiacca
Please consider that "YourEdmxFileName" must be the qualified name e.g. "YourNamespace.YourEdmxFileName", if you use namespaces in your assembly. However, you must remove the part of the namespace that equals to the name of your assembly.
Marcel
Thank you so much for this answer. It should be upvoted to number one.
CLaRGe
[MSDN says the second paragraph is wrong.](http://msdn.microsoft.com/en-us/library/cc716756.aspx) "When you use wildcard (*), the Entity Framework has to look through all the assemblies for resources with the correct name."
Craig Stuntz
A: 

The problem is due to wrong connection string. As the entity framework connection is slightly different from ordinary Ado.net connection string, it contains the following extra part

res://*/Model_Name.csdl|res://*/Model_Name.ssdl|res://*/Model_Name.msl

The model name is typically the name of the entity framework file.

Normally the file name is same as database name, but you can change the file name for edmx so make sure you provided the name of you .edmx file name in connection string for resource

Waqas Zamir
A: 

In my case, this issue was related to renaming my model's edmx file... correcting the app.config connection string for the csdl/ssdl/msl files fixed my issue.

If you're using the EF 4.0 designer to generate your csdl/ssdl/msl, these 3 "files" will actually be stored within the model's main edmx file. In this case, the post by Waqas is pretty much on the mark. It's important to understand that "Model_Name" in his example will need to be changed to whatever the current name of your model's .edmx file (without the .edmx).

Also, if your edmx file is not at the root level of your project, you need to preface Model_Name with the relative path, e.g.

res://*/MyModel.WidgetModel.csdl|res://*/MyModel.WidgetModel.ssdl|res://*/MyModel.WidgetModel.msl

would specify the csdl/ssdl/msl xml is stored in the model file 'WidgetModel.edmx' which is stored in a folder named 'MyModel'.

Janmon
A: 

I have written this helper class to create instances of ObjectContext objects when they are defined in a different project than the project using it. I parse the connection string in the config file and replace '*' by the full assembly name.

It is not perfect because it uses reflection to build the object, but it is the most generic way of doing it that I could find.

Hope it helps someone.

public static class EntityHelper<T> where T : ObjectContext
{
    public static T CreateInstance()
    {
        // get the connection string from config file
        string connectionString = ConfigurationManager.ConnectionStrings[typeof(T).Name].ConnectionString;

        // parse the connection string
        var csBuilder = new EntityConnectionStringBuilder(connectionString);

        // replace * by the full name of the containing assembly
        csBuilder.Metadata = csBuilder.Metadata.Replace(
            "res://*/",
            string.Format("res://{0}/", typeof(T).Assembly.FullName));

        // return the object
        return Activator.CreateInstance(typeof(T), csBuilder.ToString()) as T;
    }
}
lau
A: 

For all of you SelftrackingEntities Users , if you have followed the Microsoft Walk-through and separated the Object context class into the wcf service project (by linking to the context .tt) so this answer is for you :

part of the shown answers in this post that includes code like :

... = string.Format("res://{0}/YourEdmxFileName.csdl|res://{0}/YourEdmxFileName.ssdl|res://{0}/YourEdmxFileName.msl", 
        typeof(YourObjectContextType).Assembly.FullName); 

WILL NOT WORK FOR YOU !! the reason is that YourObjectContextType.Assembly now resides in a different Assembley (inside the wcf project assembly) ,

So you should replace YourObjectContextType.Assembly.FullName with -->

ClassTypeThatResidesInEdmProject.Assembly.FullName 

have fun.

_Avishay_
A: 

I was able to resolve this in Visual Studio 2010, VB.net (ASP.NET) 4.0.

During the entity model wizard, you will be able to see the entity connection string. From there you can copy and paste into your connection string.

The only thing I was missing was the "App_Code." in the connections string.

entityBuilder.Metadata = "res://*/App_Code.Model.csdl|res://*/App_Code.Model.ssdl|res://*/App_Code.Model.msl"

Christian

http://internetengineer.com/

InternetEngineer.com
A: 

Another cause for this exception is when you include a related table in an ObjectQuery, but type in the wrong navigation property name.

Example:

var query = (from x in myDbObjectContext.Table1.Include("FKTableSpelledWrong") select x);
soslo
A: 

For my case, it is solved by changing the properties of edmx file. 1- Open the edmx file 2- Right click on any place of the edmx desiner 3- choose properties 4- update Property called "Metadata Artifact Processing" to "Embed in Output Assembly"

this solved the problem for me. The problem is, when the container try to find the meta data, it cant find it. so simply make it in the same assembly. this solution will not work if you have your edmx files in another assembly

A: 

Any ideas how to override the value returned from the connection string (per the examples above using a helper function) when dealing with WCF Data Services? In that case, there is no ObjectContext directly created; instead, it is done behind the scenes when the service is created:

public class MyDataService : DataService<MyModelContainer> { ... }

BigA