DevelopMENTAL Madness

Tuesday, February 10, 2009

Entity Framework: Connection Strings

<add name="AdventureWorksEntities" 
    connectionString="metadata=.\AdventureWorks.csdl|.\AdventureWorks.ssdl|.\AdventureWorks.msl;
    provider=System.Data.SqlClient;provider connection string='Data Source=localhost;
    Initial Catalog=AdventureWorks;Integrated Security=True;Connection Timeout=60;
    multipleactiveresultsets=true'" providerName="System.Data.EntityClient" />

According to MSDN, the above EntityClient connection string will search in the following locations for the specified csdl, ssdl and msl resource files:

  1. The calling assembly
  2. The referenced assemblies
  3. The assemblies in the bin directory of an application

However, I have not found this to be the case. When my edmx file is in an assembly which is external to my project, for example a test project or web project, I get the following error:

System.Data.MetadataException: The specified metadata path is not valid. A valid path must be either an existing directory, an existing file with extension '.csdl', '.ssdl', or '.msl', or a URI that identifies an embedded resource.

And the stack trace includes the following path:

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.Objects.ObjectContext.RetrieveMetadataWorkspaceFromConnection()
System.Data.Objects.ObjectContext..ctor(EntityConnection connection, Boolean isConnectionConstructor)
System.Data.Objects.ObjectContext..ctor(String connectionString, String defaultContainerName)

Fortunately, the documentation also includes the syntax for explicitly referencing the resource files located in an external assembly. I’ve played around with a few different versions of this and this is the minimum information required in an EntityClient connection string:

<add name="AdventureWorksEntities" providerName="System.Data.EntityClient" 
    connectionString="metadata=res://MyCompany.Data,Culture=neutral,PublicKeyToken=null/Models.AdventureWorks.csdl
    |res://MyCompany.Data,Culture=neutral,PublicKeyToken=null/Models.AdventureWorks.ssdl
    |res://MyCompany.Data,Culture=neutral,PublicKeyToken=null/Models.AdventureWorks.msl; 
    provider=System.Data.SqlClient;provider connection string='Data Source=(local);Initial Catalog=AdventureWorks;Integrated Security=True;multipleactiveresultsets=true'"/>

This connection string assumes your assembly is named MyCompany.Data.dll and the full name of your class is MyCompany.Data.Models.AdventureWorks.

I’m sure I’ll need this myself in the future. I hope it helps you as well.

Labels: ,