MetadataException:无法加载指定的元数据资源

突然之间,我不断得到一个MetadataException实例化我生成的ObjectContext类。 App.Config中的连接字符串看起来是正确的 – 自上次工作以来没有改变 – 我试过从底层数据库重新生成一个新模型(edmx-file),没有任何改变。

任何人有任何想法?

进一步的细节:我没有改变任何属性,我没有改变任何输出程序集的名称,我没有尝试在程序集中嵌入EDMX。 我离开工作只等了10个小时,直到我回来。 然后它不再工作了。

我试过重新创建EDMX。 我试过重新创建项目。 我甚至尝试从头开始重新创建数据库。 没有运气,无论如何。

这意味着应用程序无法加载EDMX。 有几件事情可以导致这一点。

  • 您可能已将模型的MetadataArtifactProcessing属性更改为“复制到输出目录”。
  • 连接字符串可能是错误的。 我知道你说你没有改变它,但是如果你改变了其他的东西(比如说一个集会的名字),它可能还是错的。
  • 您可能正在使用后编译任务将EDMX嵌入程序集中,因为某些原因该程序集不再有效。

总之,你的问题没有足够的细节来给出准确的答案,但希望这些想法能使你走上正确的轨道。

更新:我写了一篇博文,提供更完整的疑难解答步骤 。

这个小改动有助于解决这个问题。

我有3个项目的解决方案。

 connectionString="metadata=res://*/Model.Project.csdl|res://*/Model.Project.ssdl|res://*/Model.Project.msl; 

改成

 connectionString="metadata=res://*/; 

当Edmx在一个项目中,并且从另一个项目中使用它时,可以得到这个异常。

原因是Res://*/是一个指向CURRENT程序集中资源的URI。 如果Edm被定义在与正在使用它的代码不同的程序集中,那么res:// * /将不起作用,因为找不到该资源。

而不是指定'*',您需要提供程序集的全名(包括公钥标记)。 例如:

 res://YourDataAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=abcdefabcedf/YourEdmxFileName.csdl|res://... 

构建连接字符串的更好方法是使用EntityConnectionStringBuilder:

 public static string GetSqlCeConnectionString(string fileName) { var csBuilder = new EntityConnectionStringBuilder(); csBuilder.Provider = "System.Data.SqlServerCe.3.5"; csBuilder.ProviderConnectionString = string.Format("Data Source={0};", fileName); csBuilder.Metadata = string.Format("res://{0}/YourEdmxFileName.csdl|res://{0}/YourEdmxFileName.ssdl|res://{0}/YourEdmxFileName.msl", typeof(YourObjectContextType).Assembly.FullName); return csBuilder.ToString(); } public static string GetSqlConnectionString(string serverName, string databaseName) { SqlConnectionStringBuilder providerCs = new SqlConnectionStringBuilder(); providerCs.DataSource = serverName; providerCs.InitialCatalog = databaseName; providerCs.IntegratedSecurity = true; var csBuilder = new EntityConnectionStringBuilder(); csBuilder.Provider = "System.Data.SqlClient"; csBuilder.ProviderConnectionString = providerCs.ToString(); csBuilder.Metadata = string.Format("res://{0}/YourEdmxFileName.csdl|res://{0}/YourEdmxFileName.ssdl|res://{0}/YourEdmxFileName.msl", typeof(YourObjectContextType).Assembly.FullName); return csBuilder.ToString(); } 

如果仍然遇到异常,请在反射器中打开程序集并检查.csdl,.ssdl和.msl文件的文件名。 当资源名称与元数据值中指定的名称不同时,它不起作用。

我有一个类似的错误。 我已经重新创建了这个项目(长篇小说),并且从旧项目中抽出了一切。 我之前并没有意识到我的模型曾经在名为“模型”的目录中,现在已经在名为“模型”的目录中。 一旦我改变了我的Web.Config从这个连接:

 <add name="RecipeManagerEntities" connectionString="metadata=res://*/Model.Recipe.csdl 

对此:

 <add name="RecipeManagerEntities" connectionString="metadata=res://*/Models.Recipe.csdl 

一切正常(将Model更改为Models )。 请注意,我必须在这个字符串中更改这三个地方。

还有一个快速的方法来检查没有反射器的型号名称….寻找目录

… obj / {config output} / edmxResourcesToEmbed

并检查.csdl,.msl和.ssdl资源文件是否存在。 如果它们在子目录中,则子目录的名称必须预先添加到模型名称中。

例如,我的三个资源文件在一个子目录Data中 ,所以我的连接字符串必须是

metadata = res:// * / Data .MyModel.csdl | res:// * / Data .MyModel.ssdl | res:// * / Data .MyModel.msl;

(与元数据= res://*/MyModel.csdl | res://*/MyModel.ssdl | res://*/MyModel.msl;)。

我也有这个问题,这是因为我的web.config中的连接字符串与我的EDMX所在的程序集的app.config中的连接字符串略有不同。 不知道为什么它改变了,但这是两个不同的版本。

App.config中:

 <add name="SCMSEntities" connectionString="metadata=res://*/Model.SMCSModel.csdl|res://*/Model.SMCSModel.ssdl|res://*/Model.SMCSModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=SANDIEGO\sql2008;initial catalog=SCMS;integrated security=True;multipleactiveresultsets=True;application name=EntityFramework&quot;" providerName="System.Data.EntityClient" /> 

Web.config文件:

 <add name="SCMSEntities" connectionString="metadata=res://*/Model.SCMSModel.csdl|res://*/Model.SCMSModel.ssdl|res://*/Model.SCMSModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=SANDIEGO\sql2008;initial catalog=SCMS;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" /> 

什么修复它只是简单地复制app.config字符串(注意最后的小差异 – 而不是“ App=EntityFramework ”它想要“ application name=EntityFramework ”)到web.config和问题解决了。 🙂

当我意外地将edmx文件的构建操作(在IDE中的属性下出现)从“EntityDeploy”切换到“无”时,发生了这种情况。 EntityDeploy是为您填充元数据的内容:请参阅http://msdn.microsoft.com/en-us/library/cc982037.aspx

我刚刚花了30分钟的时间。 我会重命名实体对象,重命名配置文件中的条目,但还有更多…您必须更改对csdl的引用

很容易错过 – 如果你正在重新命名,确保你得到的一切 ….

我能够在Visual Studio 2010,VB.net(ASP.NET)4.0中解决这个问题。

在实体模型向导期间,您将能够看到实体连接字符串。 从那里你可以复制并粘贴到你的连接字符串。

我唯一缺少的是“App_Code”。 在连接字符串中。

 entityBuilder.Metadata = "res://*/App_Code.Model.csdl|res://*/App_Code.Model.ssdl|res://*/App_Code.Model.msl" 

我有同样的问题。 我用反射器查看了我的编译后的DLL,发现资源名称不对。 我改名了,现在看起来不错。

对于我的情况,它通过更改edmx文件的属性来解决。

  1. 打开edmx文件
  2. 右键单击EDMX设计器的任何地方
  3. 选择属性
  4. 更新称为“元数据构件处理”的属性以“嵌入输出程序集”

这为我解决了这个问题。 问题是,当容器试图找到元数据,它无法找到它。 所以只需在同一个程序集中进行。 如果您在另一个程序集中有您的edmx文件,此解决方案将不起作用

我花了一整天在这个错误

如果你正在使用n-tear architecture

或者您尝试将由EDMX表单DataAccessLayer生成的separate ModelsDomainModelLayer

也许你会得到这个错误

  1. 首先排除故障的步骤是确保webconfig (UILayer)appconfig (DataAccessLayer)中的连接字符串是相同的
  2. 其次是connection string非常重要

     connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provid..... 

    这是问题

从地球上我得到Model或任何.csdl在我的连接字符串,他们在哪里

在这里我们的解决方案看图片

在这里输入图像描述

希望对你有所帮助

最终的解决方案(即使在其他两台机器上重新创建数据库,以及EDMX和其他杂项)也不使用实体框架的第一版。 期待在.NET 4.0中再次评估它。

再次遇到同样的问题,搜索了一个答案,我终于找到了一个同样的问题。 看起来连接字符串不是由Visual Studio的向导正确生成的,并且到元数据资源的链接缺少重要的路径。

v1.0错误?:无法加载指定的元数据资源。 脚本!=模型

更新2013-01-16 :已经过渡到几乎完全使用EF代码优先实践(即使与现有的数据库),这个问题不再是一个问题。 对我来说,这是一个可行的解决方案,以减少自动生成的代码和配置的混乱,增加我自己对产品的控制。

我的问题和解决方案,症状是相同的“无法加载指定的元数据资源”,但根本原因是不同的。 我在解决方案中有两个项目是EntityModel,另一个是解决方案。 我实际上删除并重新创建了EntityModel中的EDMX文件。

解决方案是,我不得不回到Web应用程序项目,并将此行添加到配置文件。 新的模型已经改变了一些在“其他”项目的Web.Config文件中必须重复的项目。 旧的配置不再好。

  <add name="MyEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl; provider=System.Data.SqlClient; provider connection string=&quot; data source=Q\DEV15;initial catalog=whatever; user id=myuserid;password=mypassword; multipleactiveresultsets=True; application name=EntityFramework&quot;" providerName="System.Data.EntityClient" /> 

经过几个小时的谷歌搜索,并试图解决任何建议的解决方案工作。 我在这里列出了几个解决方案。 我也注意到了那个为我工作的人。 (我使用的是EF版本6.1.1和SQL服务器2014 – 但是较旧的数据库)

  1. 重建项目并重试。
  2. 关闭并打开VS – 我不知道这是如何工作的
  3. 确保如果您已经将.EDMX文件放在一个目录中,请确保您的目录包含在ConnectionString中。 例如我的DAL文件夹里面。 所以它看起来像这样: connectionString="metadata=res://*/DAL.nameModel.csdl|res://*/DAL.nameModel.ssdl|res://*/DAL.nameModel.msl; (这些是文件。看到它们,你可以在解决方案资源管理器的〜/ obj / ..目录下切换显示所有文件)

…还有很多我曾经尝试的[如:将EntityFramework版本恢复到更高版本(不确定)]


什么对我有效:

从这篇文章这里 ,它帮助我解决了我的问题。 我刚刚在EDMX文件中将ProviderManifestToken="2012"更改为ProviderManifestToken="2008" 。 去做这个:

Solution Explorer

  1. 右键点击文件.edmx
  2. 打开用..
  3. 编辑器XML
  4. 在2008年更改ProviderManifestToken =“XXXX”

我希望有帮助。

在我的情况下,这个问题是关系到重命名我的模型的edmx文件…更正解决我的问题的csdl / ssdl / msl文件的app.config连接字符串。

如果您使用EF 4.0设计器生成csdl / ssdl / msl,则这3个“文件”实际上将存储在模型的主edmx文件中。 在这种情况下,Waqas的帖子已经非常好了。 理解他的例子中的“Model_Name”将需要更改为模型的.edmx文件的当前名称(不带.edmx),这一点很重要。

另外,如果您的edmx文件不在您的项目的根目录下,则需要在相对路径前加上Model_Name,例如

 res://*/MyModel.WidgetModel.csdl|res://*/MyModel.WidgetModel.ssdl|res://*/MyModel.WidgetModel.msl 

将指定csdl / ssdl / msl xml存储在模型文件“WidgetModel.edmx”中,该文件存储在名为“MyModel”的文件夹中。

我已经编写了这个助手类来创建ObjectContext对象的实例,当它们在与使用它的项目不同的项目中定义时。 我解析配置文件中的连接字符串,并用完整的程序集名称替换“*”。

这不是完美的,因为它使用反射来构建对象,但它是我能找到的最通用的方法。

希望它可以帮助别人。

 public static class EntityHelper<T> where T : ObjectContext { public static T CreateInstance() { // get the connection string from config file string connectionString = ConfigurationManager.ConnectionStrings[typeof(T).Name].ConnectionString; // parse the connection string var csBuilder = new EntityConnectionStringBuilder(connectionString); // replace * by the full name of the containing assembly csBuilder.Metadata = csBuilder.Metadata.Replace( "res://*/", string.Format("res://{0}/", typeof(T).Assembly.FullName)); // return the object return Activator.CreateInstance(typeof(T), csBuilder.ToString()) as T; } } 

对于你们SelftrackingEntities用户,如果你已经关注了Microsoft Walk-through,并将Object上下文类分离到wcf服务项目(通过链接到上下文.tt),所以这个答案是给你的:

这篇文章中显示的部分答案包括如下代码:

 ... = string.Format("res://{0}/YourEdmxFileName.csdl|res://{0}/YourEdmxFileName.ssdl|res://{0}/YourEdmxFileName.msl", typeof(YourObjectContextType).Assembly.FullName); 

不适合你! 原因是YourObjectContextType.Assembly现在驻留在不同的Assembley(在wcf项目组件中),

所以你应该用 – >替换YourObjectContextType.Assembly.FullName

 ClassTypeThatResidesInEdmProject.Assembly.FullName 

玩的开心。

我有这个相同的错误信息的问题。 通过关闭并重新打开Visual Studio 2010解决了我的问题。

有同样的问题,因为我重命名了一个程序集。

我还必须在项目Properties / AssemblyInfo.cs中的AssemblyTitle和AssemblyProduct属性中重命名它,同时删除并重新添加对edmx文件的引用。

然后,它工作得很好。

有了同样的问题,我从数据库重新创建edmx。 解决我的问题。

除了我正在将一个现有的.edmx导入到一个新的项目,并且基本的命名空间并不重要,它被导入到一个不同的子目录,所以我也必须更新连接字符串在Web.Config里面三个地方,包括不同的子目录命名:

当解决方案文件夹中包含项目的解决方案移到“解决方案根目录”时(为了克服Mvc3AppConverter因项目位置而导致的可疑错误),我遇到了同样的问题。

尽管在所有*项目引用之后编译的解决方案都是根据需要重新添加的,但是在网站启动时却出现了错误。

EDMX是被移动的项目之一(“数据”项目),但是当然缺少对Data项目的引用不会导致编译错误,只是运行时错误。

只需将缺少的引用添加到主项目中就可以解决此问题,根本不需要编辑连接。

我希望这可以帮助别人。

一个可怜的app.config或web.config文件可以做到这一点..我已经将app.config连接字符串复制到我的UI中的web.config,并最终输入:

 <connectionStrings> <connectionStrings> <add name="name" connectionString="normalDetails"/> </connectionStrings> </connectionStrings> 

我只是没有引用我的类库包含EDMX文件。

我的理论是,如果你有多个同名的edmx文件(例如Model1),它会给出这个异常。 当我决定将所有的edmx文件(坐在不同的项目中)命名为Model1时,我遇到了同样的问题,因为我认为它们应该是独立的。

造成此异常的另一个原因是在ObjectQuery中包含相关表格,但输入了错误的导航属性名称。

例:

 var query = (from x in myDbObjectContext.Table1.Include("FKTableSpelledWrong") select x); 

有时包含该模型的程序集未加载:

  [TestMethod] public void TestOpenWithConfigurationAfterExplicit() { String dummy = typeof(MallApp).Assembly.FullName; //force the assembly loaded. using (DbContext ctx = new DbContext("name=MyContainer)) { } } 

MallApp类型与实体模型位于同一个程序MallApp 。 如果没有显式加载,则会抛出System.Data.MetadataException异常。

至于我,我分开了数据访问层和用户界面层。 所以我有每个图层的实体连接字符串。

在我修改这两个分离的连接字符串之前,我仍然发现下面的错误。

 Unable to load the specified metadata resource 

所以我使这两个层(DAL,UI)是相同的连接字符串,它是完美的。

我的解决方案是使所有连接字符串都是相同的,无论他们已经提出

当我把元数据问题整理出来的时候,我有一个以invokation异常的形式出现的后续问题,无法找到app.config(其中我的目标不依赖于app.config)中的XXXEntities的连接字符串。 通过纯粹的运气,我发现在我的单元测试项目中引用System.Data清除了这个最后的障碍。 所以总结一下:

  1. 使用nuget将Entity Framework安装到您的单元测试项目。
  2. 确保System.Data.Entity和System.Data被引用。
  3. 按照这里所描述的顺序排列连接字符串。
  4. 将连接字符串传递给您的部分类构造函数。

我现在有一个类库中的元数据,可以从参考数据库更新,我可以在运行时将我的应用程序和单元测试指向任何服务器上的任何数据库。

附录:当我把我的edmx移动到一个文件夹时,我又得到了错误。 经过一番研究之后,我发现你希望元数据字符串看起来像:metadata = res://EPM.DAL/Models.EPM.csdl,其中EPM.DAL是程序集的名称,EPM.edmx是在模型文件夹。