实体框架连接字符串中的元数据出现问题
我有一个使用 RIA 服务的 Silverlight 4 应用程序,其中我将所有 RIA 服务特定的代码移动到一个名为“AppServices”的单独模块(WCF RIA 服务类库)。我们将主应用程序称为“Silverlight4App”。我需要针对与存储其余数据的数据库不同的数据库对用户进行身份验证。我已将 EF 模型添加到 AppServices.Web,这也是身份验证服务当前所在的位置。 Web.config 文件位于主应用程序中,即 Silverlight4App 中。
在 web.config 文件的 connectionStrings 部分中,我最初有
<add name="AuthEntities" connectionString="metadata=res://*/AuthModel.csdl|res://*/AuthModel.ssdl|res://*/AuthModel.msl;provider=... />
以下错误:
“查询‘GetUser’的加载操作失败。无法加载指定的元数据资源。”
然后我尝试了各种操作,例如:
<add name="AuthEntities" connectionString="metadata=..\..\bin\AuthModel.csdl|..\..\bin\AuthModel.ssdl|..\..\bin\AuthModel.msl;provider=... />
并收到此错误:
“查询“GetUser”的加载操作失败。指定的元数据路径无效。有效的路径必须是现有目录、扩展名为“.csdl”的现有文件” 、‘.ssdl’、‘.msl’或标识嵌入资源的 URI。”
我还尝试将元数据文件复制到各个位置。最后,我进一步了解了以下内容。
<add name="AuthEntities" connectionString="metadata=~\..\..\..\Silverlight4App.Web\Metadata\AuthModel.csdl|~\..\..\..\Silverlight4App.Web\Metadata\AuthModel.ssdl|~\..\..\..\Silverlight4App.Web\Metadata\AuthModel.msl;provider=... />
使用上述连接字符串,我收到以下错误:
“查询“GetUser”的加载操作失败。提供的连接字符串无效,因为它包含不足的映射或元数据信息。\r\n参数名称:connectionString 内部异常消息:无法确定应用程序上下文。无法解析 ASP.NET 应用程序路径。”
好吧,至少它似乎已经找到元数据文件!出于沮丧,我最终尝试简单地将整个路径硬编码到元数据文件:
<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=... />
它工作得很好!不幸的是,这是一个糟糕的解决方案,尤其是当我去部署应用程序时。
奇怪的是,我在硬编码尝试(见上文)之前尝试的尝试抱怨信息不足,但指向完全相同的文件的硬编码尝试却出现了包含足够的信息。嗯...
有什么想法吗?我肯定需要一些帮助!
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, i.e. 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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
用Reflector查看编译后的程序集,看看资源是否存在;如果是,则应该可以使用第一种方法访问它们。如果没有,那么您的部署就有问题;当然,您始终可以选择将它们部署为松散文件。如果这没有帮助,请要求更多说明,明天我将在我的办公桌前拿着手头的代码进一步解释(不久前必须处理类似的事情)。
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).
根据我的实验:通过文件系统访问时的元数据是通过
Environment.CurrentDirectory
的相对路径完成的。如果有任何东西改变了这个值,如果从 exe 路径给出,它会弄乱你的相对路径。由于此限制,使用嵌入式资源更加稳定。注意:编译为嵌入式资源时,完整资源名称与通过 EntityDeploy 编译 edmx 时不同。如果您仍然难以接受/找到元数据,请使用
ilasm
或reflector
提取已编译的资源以确定资源名称...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 theilasm
orreflector
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 ...解决这个问题的最佳方法是创建一个工厂来生成 EF 对象。工厂可以传入一个 edmxconnection 对象,该对象可以这样生成:(请原谅 VB)
然后可以通过构造函数将该连接传递到 Context 实例中。
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)
This connection can then be passed into the Context instance via the constructor.