我有一个使用RIA服务的Silverlight 4应用程序,我将所有RIA服务特定代码移动到一个名为“AppServices”的单独模块(WCF RIA Services类库)。我们将主应用程序称为“Silverlight4App”。我需要针对与存储其余数据的数据库不同的数据库对用户进行身份验证。我已经向AppServices.Web添加了EF模型,这也是身份验证服务当前所在的位置。 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=... />
它工作得很好!!不幸的是,这是一个 糟糕的 解决方案,特别是当我去部署应用程序时。
在硬编码尝试之前尝试的尝试(见上文)似乎很奇怪抱怨信息不足而且硬编码尝试指向完全相同的文件,似乎包含足够的信息。嗯...
有什么想法吗?我当然可以使用一些帮助!
答案 0 :(得分:2)
使用Reflector查看已编译的程序集以查看资源是否存在;如果是,则应使用第一种方法访问它们。如果没有,那么您的部署会出现问题;您总是可以选择将它们部署为松散文件。如果这没有帮助,请求更多说明,明天我将在我的办公桌旁,手头的代码进一步解释(不得不在不久前处理这样的事情)。
答案 1 :(得分:2)
从我的实验中:通过文件系统访问的元数据是通过Environment.CurrentDirectory
的相对路径完成的。如果有什么东西在改变那个值,那么如果从exe路径给出,它将会破坏你的相对路径。由于这种约束,使用嵌入式资源更稳定。
注意:在编译为嵌入式资源时,完整资源名称与通过EntityDeploy
编译edmx时不同。如果您仍然难以接受/找到元数据,请使用ilasm
或reflector
提取已编译的资源以确保资源名称...
答案 2 :(得分:1)
解决此问题的最佳方法是创建一个工厂来生产EF对象。工厂可以传入一个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
然后可以通过构造函数将此连接传递给Context实例。