Entity Framework FAQ: Error Messages

Entity Framework FAQ: Error Messages

    

Back to EF FAQs Table of Contents  

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.

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.

MSDN documents EF connection strings generally. But the cause of this error is specifically the `metadata` parameter. This parameter tells the Entity Framework where to find your EDMX at runtime. Detailed information about the structure of this parameter and how to troubleshoot it can be found in this article.

 

Unable to create a constant value of type 'SomeType'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.


You may see the following error when executing a LINQ to Entities query:

System.NotSupportedException
Unable to create a constant value of type 'System.Object'.
Only primitive types ('such as Int32, String, and Guid') are supported in this context.

This message can mean you're doing an equality comparison on an instance, instead of its key. This is not supported.

So the second query below won't work:

    var first = Context.Foos.First();
    var again = Context.Foos.Where(f => f ==
first).Single();

...but this, corrected version, will:

    var again = Context.Foos.Where(f => f.Id == first.Id).Single();

LINQ to Entities queries are converted to SQL, so there is no concept of reference equality. But comparing based on the primary key will work.w

This problem can also be caused by boxing:


    var wrong = Context.Foos.Where(f => f.SomeBoolean.Equals(true)).Single(); // runtime error
    var right = Context.Foos.Where(f => f.SomeBoolean
).Single();              // works

In the first case, the Boolean true is boxed by the call to Equals(Object obj). The second example doesn't do this, and works.

Cannot compare elements of type 'MyNamespace.SomeComplexType'. Only primitive types (such as Int32, String, and Guid) and entity types are supported.

LINQ to Entities doesn't allow you to directly compare complex types, even with null. By contrast, you can compare entity types with null. 

    var wrong = Context.Foos
                       .Where(f => f.SomeComplexType == null)
                       .Single();                                        // runtime error
    var right = Context.Foos
                       .Where(f => f.SomeComplexType.SomeString == null
)
                       .Single();                                        // works
    var works = Context.Foos
                       .Where(f => f.SomeEntity == null
)
                       .Single();                                        // works


In fact, complex types are rarely null in the real world anyway, as they are initialized by the EF, even with lazy loading disabled, and even if never directly assigned. So there is usually not a reason to do this anyway.

The methods 'Single' and 'SingleOrDefault' can only be used as a final query operation. Consider using the method 'FirstOrDefault' in this instance instead.

In a LINQ to Entities query, you can use either FirstOrDefault() or SingleOrDefault as the final query operation:

    var right = Context.Foos
                       .Where(f => f.SomeBoolean
)
                       .FirstOrDefault();                                        // works
    var works = Context.Foos
                       .Where(f => f.SomeBoolean)
                       .SingleOrDefault();                                       // works



However, inside the query, you cannot use SingleOrDefault:
    var wrong = Context.Foos
                       .Where(f => f.SomeBoolean
)
                       .Select(f => f.Bars.SingleOrDefault())
                       .SingleOrDefault();                                       // Runtime error
    var right = Context.Foos
                       .Where(f => f.SomeBoolean)
                       .Select(f => f.Bars.FirstOrDefault())
                       .SingleOrDefault();                                       // works



Note that the final SingleOrDefault is always OK, but we had to change the one inside the query to FirstOrDefault. The reason for this is how SingleOrDefault is implemented. It tells the DB server to return the first two records and then throws an exception if more than one is returned. The LINQ to Entities query -- everything up until the final SingleOrDefault -- will be converted to SQL. That error behavior is not straightforward to express in a pure SQL query. 

Back to EF FAQs Table of Contents
Sort by: Published Date | Most Recent | Most Useful
Comments
  • Ed Price - MSFT edited Revision 12. Comment: Space formatting

Page 1 of 1 (1 items)