Sunday 23 August 2009

Navigation Properties and Entity Inheritence

Symptom
Navigation Properties are not supported on derived entity types
The full error message reads something like this:
Navigation Properties are not supported on derived entity types. Entity Set [BaseSetName] has a instance of type [DerivedType], which is an derived entity type and has navigation properties. Please remove all the navigation properties from type [DerivedType].
Cause

Sounds straight forward enough, right? Remove the navigation properties from the derived type. Hang on, my navigation properties are specific to the derived type, not the base type. Does this mean I can't navigate from the derrived type at all? As it turns out, that's right - you can't (see Microsoft's response). So, the equation as I see it as follows:
  • You can use inheritance in your EF model but not with data services. You need to write the WCF service and client proxy by hand.
  • Or, you can remodel you entities without inheritance and use ADO.NET data services.
Apparently this is going to be fixed in v2. I am disappointed by this: for me, a big factor in using EF is the support for entity inheritance. Not happy!

Debugging ADO.NET Data Services

Symptom

ADO.NET data service request fails with the following incredibly unhelpful message: "An error occurred while processing this request":

Cause

The cause could be anything, but to find out what the underlying error is you need to enable verbose errors and include exception details in faults: see this post for details.

Entity Framework Metadata Resources

When you create an EF model, the metadata is defined in an .EDMX file. This file contains three sections:
  1. SSDL = storage model: defines the 'shape' of the database in which the data is stored. This includes the tables, their columns and the relationships between tables. All data types are defined in database types e.g., varchar.
  2. CSDL = conceptual model: defines the 'shape' of your entity model. This includes the classes, their properties, and the relationship between classes. All data types are defined in .Net types e.g., System.String or System.Int32.
  3. MSL = mapping model: describes how the conceptual model is mapped onto the storage model. E.g., each property in the conceptual model is mapped to a column in the storage model.
Where does all this information go?

When you compile a project that contains an .EDMX file, three resources are embedded into your assembly. Not surprisingly, these resources are yourContainer.SSDL, yourContainer.CSDL, and yourContainer.MSL (where yourContainer is the name of your entity container). If you open your assembly in .Net Reflector you'll see they contain, verbatim, the XML from each section of the .EDMX.

EntityContainer name could not be found in the mapping and metadata information

Symptom

ADO.NET entity framework throws the following exception when creating an entity context:

System.ArgumentException: The specified default EntityContainer name [NAME] could not be found in the mapping and metadata information. Parameter name: defaultContainerName
at System.Data.Metadata.Edm.ClrPerspective.SetDefaultContainer(String defaultContainerName)
at System.Data.Objects.ObjectContext.set_DefaultContainerName(String value)
at System.Data.Objects.ObjectContext..ctor(String connectionString, String defaultContainerName)

Cause

This error can mean a mismatch between the metadata referenced in the connection string (i.e., in config) and theembedded resource in your assembly. You have probably noticed that entity framework connection strings contain a much more than typical db connection strings. In fact the db connection is just one of its properties. So what are the other properties?

  1. metadata: lists the three metadata resources required by entity framework (CSDL, SSDL, MSL). For more info on these see entity framework metadata resources.
  2. provider: the .Net data provider
  3. provider connection string: the underlying db connection string (this is the 'typical' ado.net connection string). Note that this string is quoted inside the EF CS using "
Now if the names of any of the resources in the metadata property don't match the resources actually embedded in your assembly, then you'll get this error. How do I tell what the names of the embedded resources are? Open your assembly using .Net Reflector. Look under resources - you should see the three EF metadata resources. Check your connection string and make sure they match.