简体   繁体   中英

Trouble with metadata in Entity Framework connection string

I have a Silverlight 4 app using RIA Services in which I moved all of the RIA Services-specific code to a separate module (a WCF RIA Services class library) called "AppServices". Let's call the main app "Silverlight4App". I need to authenticate the users against a different database than the database where the rest of the data is stored. I have added an EF model to AppServices.Web, which is also where the authentication service currently resides. The Web.config file is in the main app, ie in Silverlight4App.

In the connectionStrings section of the web.config file, I originally had this:

<add name="AuthEntities" connectionString="metadata=res://*/AuthModel.csdl|res://*/AuthModel.ssdl|res://*/AuthModel.msl;provider=... />

and I got the following error:

"Load operation failed for query 'GetUser'. Unable to load the specified metadata resource."

Then I tried various things such as:

<add name="AuthEntities" connectionString="metadata=..\..\bin\AuthModel.csdl|..\..\bin\AuthModel.ssdl|..\..\bin\AuthModel.msl;provider=... />

and got this error:

"Load operation failed for query 'GetUser'. 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."

I also tried copying the metadata files to various locations. In the end, I got a little further with the following.

<add name="AuthEntities" connectionString="metadata=~\..\..\..\Silverlight4App.Web\Metadata\AuthModel.csdl|~\..\..\..\Silverlight4App.Web\Metadata\AuthModel.ssdl|~\..\..\..\Silverlight4App.Web\Metadata\AuthModel.msl;provider=... />

With the above connection string, I got the following error:

"Load operation failed for query 'GetUser'. The supplied connection string is not valid, because it contains insufficient mapping or metadata information.\\r\\nParameter name: connectionString Inner exception message: Unable to determine application context. The ASP.NET application path could not be resolved."

Well, at least it seems to have found the metadata files! Out of frustration I finally tried simply hard-coding the entire path to the metadata files:

<add name="AuthEntities" connectionString="metadata=C:\Users\...\Silverlight4App.Web\Metadata\AuthModel.csdl|C:\Users\...\Silverlight4App.Web\Metadata\AuthModel.ssdl|C:\Users\...\Silverlight4App.Web\Metadata\AuthModel.msl;provider=... />

It worked perfectly!! Unfortunately, it's a lousy solution, especially when I go to deploy the application.

It seems odd that the attempt that I tried just before the hard-coded attempt (see above) complained that there was insufficient information and yet the hard-coded attempt, which pointed to the exact same files , appears to contain sufficient information. Hmm...

Any ideas? I could surely use some help!

Look in the compiled assembly with Reflector to see if the resources are there; if they are, they should be accessible using the first method. If not then there's something wrong with your deployment; you always have the option to deploy them as loose files of course. If this doesn't help, ask for more clarification, I'll be at my desk tomorrow with the code at hand to explain further (had to deal with something like this a while ago).

From my experimentation : the metadata when accessed via file system is done by relative path to Environment.CurrentDirectory . If anything is changing that value it will mess up your relative paths if given from the exe path. Due to this constraint it is more stable to use an embedded resource.

Note: When compiling as an embedded resource the full resource name is different from when compiling an edmx via EntityDeploy . Use the ilasm or reflector to extract the compiled resources to be sure of the resource name if you are still having difficulty getting the metadata to be accepted/found ...

The best way to tackle this is create a factory to produce your EF object. The factory can pass in a edmxconnection object which can be generated as such: (Excuse the VB)

Public Shared Function GetEDMXConnectionString(Of T As ObjectContext)(Optional ByVal connectionString As String = "") As EntityConnection
  Dim dbConnection As New SqlConnection(connectionString)
  Dim resourceArray As String() = {"res://*/"}
  Dim assemblyList As Assembly() = {GetType(T).Assembly}
  Dim metaData As New MetadataWorkspace(resourceArray, assemblyList)
  Dim edmxConnection As New EntityConnection(metaData, dbConnection)

  Return edmxConnection
End Function

This connection can then be passed into the Context instance via the constructor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM