简体   繁体   English

实体框架连接字符串中的元数据问题

[英]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". 我有一个使用RIA服务的Silverlight 4应用程序,其中我将所有RIA服务特定代码移动到一个名为“AppServices”的单独模块(WCF RIA Services类库)。 Let's call the main app "Silverlight4App". 我们将主应用程序称为“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. 我已经向AppServices.Web添加了EF模型,这也是身份验证服务当前所在的位置。 The Web.config file is in the main app, ie in Silverlight4App. Web.config文件位于主应用程序中,即Silverlight4App中。

In the connectionStrings section of the web.config file, I originally had this: 在web.config文件的connectionStrings部分中,我最初有这个:

<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." “查询'GetUser'的加载操作失败。无法加载指定的元数据资源。”

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." “查询'GetUser'的加载操作失败。指定的元数据路径无效。有效路径必须是现有目录,扩展名为”.csdl“,”。ssdl“或”.msl“的现有文件,或者标识嵌入资源的URI。“

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." “查询'GetUser'的加载操作失败。提供的连接字符串无效,因为它包含的映射或元数据信息不足。\\ r \\ nParameter name:connectionString内部异常消息:无法确定应用程序上下文.ASP.NET应用程序路径无法解决。“

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; 查看带有Reflector的已编译程序集,查看资源是否存在; 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 . 根据我的实验:通过文件系统访问时的元数据是通过Environment.CurrentDirectory的相对路径完成的。 If anything is changing that value it will mess up your relative paths if given from the exe path. 如果有什么东西在改变那个值,那么如果从exe路径给出,它将会破坏你的相对路径。 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 . 注意:编译为嵌入式资源时,完整资源名称与通过EntityDeploy编译edmx时不同。 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 ... 如果您仍然难以接收/找到元数据,请使用ilasmreflector提取已编译的资源以确保资源名称...

The best way to tackle this is create a factory to produce your EF object. 解决这个问题的最佳方法是创建一个工厂来生产EF对象。 The factory can pass in a edmxconnection object which can be generated as such: (Excuse the VB) 工厂可以传入一个edmxconnection对象,可以这样生成:(请原谅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. 然后可以通过构造函数将此连接传递到Context实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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