使用实体框架实体连接时出现MetadataException

Shi*_*iji 66 entity-framework

这段代码:

using (EntityConnection conn = new EntityConnection("name=ELSCommonEntities"))
{
  conn.Open();
}
Run Code Online (Sandbox Code Playgroud)

给我以下错误:

Test method ELS.Service.Business.IntegrationTest.Base.ServiceBaseIntegrationTest.StartLoggingTestMethod threw exception:  System.Data.MetadataException: Unable to load the specified metadata resource..
Run Code Online (Sandbox Code Playgroud)

使用以下堆栈跟踪:

System.Data.Metadata.Edm.MetadataArtifactLoaderCompositeResource.LoadResources(String assemblyName, String resourceName, ICollection`1 uriRegistry, MetadataArtifactAssemblyResolver resolver)
System.Data.Metadata.Edm.MetadataArtifactLoaderCompositeResource.CreateResourceLoader(String path, ExtensionCheck extensionCheck, String validExtension, ICollection`1 uriRegistry, MetadataArtifactAssemblyResolver resolver)
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.EntityClient.EntityConnection.InitializeMetadata(DbConnection newConnection, DbConnection originalConnection, Boolean closeOriginalConnectionOnFailure)
System.Data.EntityClient.EntityConnection.Open()
ELS.Service.Business.Base.ServiceBase.StartLogging(String userWindowsLogon) in C:\C-TOM\ELS-RELEASE1\ELS.Service.Business\Base\ServiceBase.cs: line 98
ELS.Service.Business.IntegrationTest.Base.ServiceBaseIntegrationTest.StartLoggingTestMethod() in C:\C-TOM\ELS-RELEASE1\ELS.Service.Business.IntegrationTest\Base\ServiceBaseIntegrationTest.cs: line 65
Run Code Online (Sandbox Code Playgroud)

但是,此代码使用相同的连接字符串:

using (ELSCommonEntities db = new ELSCommonEntities())
{
    var res = from c in db.Logging
              select c;

    int i = res.Count();
}
Run Code Online (Sandbox Code Playgroud)

不给出错误.

连接字符串是:

<add name="ELSCommonEntities" connectionString="metadata=res://*/Common.CommonModel.csdl|res://*/Common.CommonModel.ssdl|res://*/Common.CommonModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=localhost;Initial Catalog=els5_demo;Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />
Run Code Online (Sandbox Code Playgroud)

我也在反射器中打开了dll,元数据看起来还不错.

Shi*_*iji 114

发现了问题.

标准元数据字符串如下所示:

metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl
Run Code Online (Sandbox Code Playgroud)

这在大多数情况下都可以正常工作.但是,在某些(包括我的)实体框架中,混淆并且不知道要查看哪个dll.因此,将元数据字符串更改为:

metadata=res://nameOfDll/Model.csdl|res://nameOfDll/Model.ssdl|res://nameOfDll/Model.msl
Run Code Online (Sandbox Code Playgroud)

它会奏效.正是这个链​​接让我走上正轨:

http://itstu.blogspot.com/2008/07/to-load-specified-metadata-resource.html

虽然我有相反的问题,但没有在单元测试中工作,但在服务中工作.

  • "某些情况"是指您有多个具有相同名称的edmx文件(例如Model1). (4认同)
  • 你给出的链接让我得到答案,所以你得到我的upvote!我和他一起战斗了半天.我曾尝试过res:// NameOfDLL/...但没有成功.但是,我终于使用了res:// NameOfAssembly/...在这种情况下,它们是相同的名称,除了程序集名称末尾没有.dll. (3认同)
  • 我在生成连接字符串之后更改了模型的命名空间,在根据您的指令修复了连接字符串后,它运行正常. (3认同)
  • 我正在投票,因为这解决了我的问题.谢谢! (3认同)

小智 45

我有相同的错误消息,问题也是连接字符串的元数据部分,但我不得不深入挖掘解决它,并希望分享这个小块:

元数据字符串由三个部分组成,每个部分如下所示:

res://
      (assembly)/
      (model name).(ext)
Run Code Online (Sandbox Code Playgroud)

其中ext是"csdl","ssdl"和"msl".

对于大多数人来说,汇编可能是"*",这似乎表明将搜索所有已加载的程序集(我没有对此进行过大量的测试).这部分对我来说不是问题,所以我不能评论你是否需要程序集名称或文件名(即有或没有".dll"),虽然我已经看到这两个建议.

型号的部分应该是名称和命名空间的.edmx文件的,相对于您的装配.因此,如果您有一个My.DataAccess程序集并在Models文件夹中创建DataModels.edmx,则其全名为My.DataAccess.Models.DataModels.在这种情况下,您的元数据中将包含"Models.DataModels.(ext)".

如果您移动或重命名.edmx文件,则需要手动更新元数据字符串(根据我的经验),并且记住更改相对命名空间会省去一些麻烦.

  • 谢谢!互联网上有100个答案,但这是其中任何一个最有用的附录.一个明显的例子:在`DalProject.dll`中你有一个文件夹`Client`,里面有`Client.edmx`文件.然后用`//DalProject/Client.Client替换`//*/Client.(csdl/ssdl/msl)`.(csdl/ssdl/msl)` (6认同)

小智 14

有几种可能的捕获量.我认为最常见的错误是在连接字符串的这一部分:

RES://xxx/yyy.csdl |高分辨率://xxx/yyy.ssdl |资源://xxx/yyy.msl;

这不是魔术.一旦你理解了什么代表你就会得到正确的连接字符串.

首先是xxx部分.除了你定义EF上下文clas的程序集名称之外别无其他.通常它会像MyProject.Data.默认值为*,表示所有已加载的程序集.指定特定的程序集名称总是更好.

现在是yyy部分.这是xxx程序集中的资源名称.它通常类似于.edmx文件的相对路径,带有点而不是斜线.例如Model/Catalog - Models.Catalog 获取应用程序正确字符串的最简单方法是构建xxx程序集.然后在文本编辑器中打开程序集dll文件(我更喜欢Total Commander的默认查看器)并搜索".csdl".通常,该字符串的出现次数不会超过1次.

您的最终EF连接字符串可能如下所示:

RES://MyProject.Data/Models.Catalog.DataContext.csdl |高分辨率://MyProject.Data/Models.Catalog.DataContext.ssdl |资源://MyProject.Data/Models.Catalog.DataContext.msl;

  • 在dll中搜索.超顶尖.谢谢 :) (2认同)