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


681

突然之间,我不断地MetadataException实例化生成的ObjectContext类。App.Config中的连接字符串看起来正确-自从上次使用以来就没有改变过-我已经尝试从基础数据库重新生成新模型(edmx文件)而没有任何改变。

谁有想法?

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

我尝试过重新创建EDMX。我尝试过重新创建该项目。我什至尝试从头开始重新创建数据库。没运气。


14
如果对某个具有超过20万次观看次数的特定产品有疑问,则该产品无法按照用户期望的方式运行。我希望看到微软解决这个问题。如果您有时间,可以通过以下链接为他们提供建议:visualstudio.uservoice.com/forums/121579-visual-studio
托尼·L。

解决了我的问题,方法是替换从db-layer项目复制的连接字符串。
Hardik '18

Answers:


856

这意味着应用程序无法加载EDMX。有几件事会导致此。

  • 您可能已将模型的MetadataArtifactProcessing属性更改为“复制到输出目录”。
  • 连接字符串可能是错误的。我知道您说您没有更改它,但是如果您更改了其他内容(例如,程序集的名称),则可能仍然是错误的。
  • 您可能正在使用后编译任务将EDMX嵌入到程序集中,由于某种原因该EDMX不再起作用。

简而言之,您的问题中没有足够的细节来给出准确的答案,但希望这些想法能使您走上正确的道路。

更新:我写了一篇博客文章,其中包含更完整的故障排除步骤


70
尽管我上次努力将其与内容比较实用程序进行比较,但连接字符串还是错误的。
J. Steen

16
这也是我的连接字符串。如果您的集成测试也需要在其自己的App.config中进行连接,那么在更新edmx时,事情可能会不同步。

11
好的,我通过简单地设置“嵌入”来解决它;编译,然后将其重置为另一个。那解决了我的问题。
Shimmy Weitzhandler,2010年

6
遇到相同的问题,尝试您的解决方案,想给+1,意识到我过去已经这样做过。我什至不记得以前有这个问题;)。在我的情况下,这一次是使用edmx的类库中的正确连接字符串,而在使用Web应用程序时是错误的。
Episodex 2012年

9
很棒的指南。对我来说,当我真的想要res:// * / MyModel1 ...时,我复制了另一个使用res:// * / Database.MyModel2 ...的连接字符串(数据库是我的Integration Tests项目中的文件夹)

360

这个小小的变化可以帮助解决这个问题。

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

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

改成

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

11
它为我解决了问题,但这到底意味着什么?
兰斯·费舍尔


4
@jocull:不,在很多情况下它不会起作用,在其他情况下会很慢。阅读我的博客文章以了解原因。
Craig Stuntz

6
将我的.edmx移至“模型”文件夹,但忘记更新连接字符串。很棒的指针。谢谢。本来需要我花几个小时才能弄清楚。
muruge 2012年

11
先生,您已经使一位可怜的Microsoft员工摆脱了非常生气的消费者。
松饼人2012年

115

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

原因是Res://*/一个uri,它指向CURRENT程序集中的资源。如果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文件的文件名。当资源的名称与元数据值中指定的名称不同时,它将无法使用。


8
如果在程序集中使用名称空间,请考虑“ YourEdmxFileName”必须是限定名称,例如“ YourNamespace.YourEdmxFileName”。但是,必须删除名称空间中与程序集名称相同的部分。
Marcel

5
MSDN说第二段是错误的。“当使用通配符(*)时,实体框架必须遍历所有程序集以查找具有正确名称的资源。”
Craig Stuntz 2010年

我很确定命名空间不相关,但是嵌入式文件路径是相关的。因此,即使您检查了相关edmx文件的* .Designer.cs文件,并注意到自动生成的类名称空间是MyCompany ...不管怎样,它都不应该使用。相反,路径是程序集名称,解决方案文件夹名称/文件名。例如:“元数据= res:// * / EntityModels。<文件名> .csdl |” +“ res:// * / EntityModels。<文件名> .ssdl |” +“ res:// * / EntityModels。<文件名> .msl;”
丹尼尔(Daniel)

1
@Daniel,基本上是正确的,但请注意,命名空间和嵌入式文件路径有时是相同的。您必须确保使用Reflector(或免费的替代产品)。
Craig Stuntz 2011年

它看起来像仅使用程序集名称即可工作,而没有版本号,publickeytoken等。例如:res://MyAssembly/folder.<filename>.csdl...
Ivan Ferrer Villa

67

我有一个类似的错误。我重新创建了该项目(长话短说),并将所有内容从旧项目中删除。我以前没有意识到我的模型曾经在一个名为“模型”的目录中,而现在却在一个名为“模型”的目录中。一旦我从此更改了Web.Config中的连接:

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

对此:

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

一切正常(更改ModelModels)。请注意,我必须在此字符串中更改这三个位置。


2
我将实体框架模型从模型移到了DAL。但是后来,当我在测试项目中编写测试(一周后)以测试Linq predicatebuilder时。我得到这个错误。我在测试项目App.config中修改了它在主项目的web.config中的外观-正如您在三个地方所说的那样。因此,您的简单回答使我步入正轨。
PatrikLindström2012年

是的,谢谢-检查您的文件名。不知何故我有旧名字。
PeterX

7
两者之间有区别吗?
Erwin Rooijakkers 2013年

2
@ErwinRooijakkers模型vs模型
Marc

在阅读Craig的博客之后,我发现我做了同样的事情,但是+1对于学习很重要,请记住,在“实体”类库中进行的更改不会自动在引用它的项目的配置文件中进行。/ sigh很高兴我并不孤单。
鲁芬

26

以及一种无需Reflector即可检查型号名称的快速方法。...查找目录

... obj / {config output} / edmxResourcesToEmbed

并检查.csdl,.msl和.ssdl资源文件是否存在。如果它们在子目录中,则该子目录的名称必须位于模型名称之前。

例如,我的三个资源文件都在子目录Data中,因此我的连接字符串必须为

元数据= res:// * / Data .MyModel.csdl | res:// * / Data .MyModel.ssdl | res:// * / Data .MyModel.msl;

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


这正是我的问题。为此损失了几个小时。非常感谢您的简单解释
Fernando Carvalhosa 2015年

很好的答案,实际上说明了如何找到您的字符串。并显示子文件夹具有“。” 作为定界符,而不是'\'或'/'。
cjb110

16

我也遇到了这个问题,这是因为我的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中,并解决了问题。:)


1
谢谢,这确实是我的问题。我有1个使用EF访问数据库的项目和另一个WCF项目。更改第一个项目的名称后,在我的第一个项目的App.config中更改了connectionString。所以我不得不在项目WCF中以及在​​web.config中更改connectionString :)
Volkan,

从有关docs.microsoft.com/zh-cn/dotnet/framework/data/adonet/…的 MSDN文档中:The .NET Framework data provider for SQL Server (SqlClient) supports many keywords from older APIs, but is generally more flexible and accepts synonyms for many of the common connection string keywords.实体框架连接字符串不具有这种灵活性,因此您必须仅使用它期望的关键字。
Suncat2000

13

当我不小心将edmx文件的构建操作(出现在IDE中的“属性”下)从“ EntityDeploy”切换为“ None”时,这发生了。EntityDeploy为您填充元数据:请参阅http://msdn.microsoft.com/zh-cn/library/cc982037.aspx


这是我的解决方法-复制时,我将edmx重命名为.old并尝试了一些操作,然后当我将其重命名为Build Action时,将其自身设置为none,从而得到了此错误,并将其设置为EntityDeploy解决了我的问题:)
eth0

我已将我的EDMX文件移动到另一个文件夹,并且不得不更改构建操作以使嵌入式资源名称也得以更新。谢谢!
David

这是我的解决方案;在升级到.NET Standard的过程中,我丢失了该设置。感谢您保存我的理智!
NetherGranite

11

当我在构建新的.edmx设计器之前不清理解决方案时,这会发生在我身上。因此,在构建新的.edmx设计器之前,请不要忘记清理解决方案。这有助于我跳过与此有关的更多问题。如果您是Visual Studio的新手,请提供以下导航详细信息。

单击->构建->清洁解决方案

然后单击->构建->重建解决方案

希望这可以帮助。谢谢大家


8

我刚刚度过了愉快的30分钟。我重命名了实体对象,重命名了配置文件中的条目,但是还有更多...您还必须更改对csdl的引用

很容易错过-如果您重命名,以确保你得到的一切 ....


6

我有同样的问题。我用反射器检查了我已编译的dll,发现资源名称不正确。我重命名了,现在看起来还不错。


6

就我而言,可以通过更改edmx文件的属性来解决。

  1. 打开edmx文件
  2. 右键单击EDMX设计器的任何位置
  3. 选择属性
  4. 将名为“元数据工件处理”的属性更新为“嵌入到输出程序集中”

这为我解决了问题。问题是,当容器尝试查找元数据时,它找不到。因此只需在同一装配中制作即可。如果您的edmx文件位于另一个程序集中,则此解决方案将不起作用


+1,000,000,这是我今天面临的根本问题。重组产品名称空间和合并程序集的痛苦。
Mike

6

我花了整整一天的时间来解决这个错误

如果您正在与 n-tear architecture

或者您尝试separate Models通过EDMXDataAccessLayer表单生成DomainModelLayer

也许你会得到这个错误

  1. 故障排除的第一步是确保连接字符串在webconfig (UILayer)appconfig (DataAccessLayer)相同
  2. 第二点很重要 connection string

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

    这是问题

Model从哪里来的,或者连接字符串中的任何.csdl,它们在哪里

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

在此处输入图片说明

希望对你有帮助


5

我能够在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"

不幸的是,向导中的连接字符串对于app.config不正确。@leqid建议了修复模型路径的好方法。
Der_Meister 2014年

5

经过数小时的搜寻和尝试解决之后,建议的所有解决方案均未奏效。我在这里列出了几种解决方案。我也注意到了对我有用的那个。(我使用的是EF版本6.1.1和SQL Server 2014-但使用的是较旧的数据库)

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

...以及我尝试过的许多其他操作,例如:将EntityFramework版本还原为更高版本(不确定)


对我有用的是:

从这里的这篇文章,它可以帮助我解决问题。我只是改变了我ProviderManifestToken="2012"ProviderManifestToken="2008"在EDMX文件。去做这个:

解决方案资源管理器

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

希望对您有所帮助。


在看似没有任何改变之后,我最近遇到了这个问题。尝试重新启动VS无济于事,但随后通过清洁和重建对其进行了修复。因此,对于其他人,如果您没有进行任何更改,而其余所有内容似乎都不相关,请尝试进行清理/重建。
格雷格

5

如果您正在使用其他项目中的edmx,则在连接字符串中,更改...

metadata=res://*/Data.DataModel.csdl

...至...

metadata=res://*/DataModel.csdl

的确如此,如果要将其移动到新的项目子文件夹,则需要在其folder.subfolder之前添加。
卡克马克

谢谢,这个解决方案对我有用。我已经将.edmx文件从一个项目中的目录移到了另一个项目的根目录,并且需要从我的解决方案的所有连接字符串中删除目录名。
克里斯,

4

最终的解决方案(即使在其他两台计算机以及EDMX和其他杂物上重新创建数据库之后)也不使用Entity Framework的第一版。期待在.NET 4.0中再次对其进行评估。

再次遇到相同的问题并四处寻找答案后,我终于找到了遇到相同问题的人。看来Visual Studio的向导未正确生成连接字符串,并且指向元数据资源的链接缺少重要路径。

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

2013年1月16日更新:几乎已经完全使用EF Code First做法(即使使用现有数据库)过渡到了此问题。对我来说,这是一个可行的解决方案,可以减少自动生成的代码和配置带来的混乱,并增加我对产品的控制。


4

我的问题和解决方案的症状是相同的“无法加载指定的元数据资源”,但根本原因不同。我在解决方案中有2个项目,一个是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" />

3

就我而言,此问题与重命名模型的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”的文件夹中。


3

我编写了此帮助程序类,以在与使用它的项目不同的项目中定义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;
    }
}

3

对于所有SelftrackingEntities用户,如果您已遵循Microsoft演练并将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 

玩得开心。


3

有时我在项目中看到此错误。我通过解决

1-右键单击EDMX文件

2-选择Run Custom Tool选项

3-重建项目


这对我
有用,

2

我在与此相同的错误消息中遇到问题。通过关闭并重新打开Visual Studio 2010,我的问题得到了解决。


2

由于我重命名了程序集,因此发生了同样的问题。

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

然后就很好了。


2

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


2
不幸的是,该方法解决并治疗了症状,而不是原因。
Clarice Bouwer 2014年


1

除了将现有的.edmx导入到新项目中外,我还具有与Rick相同的问题和解决方案,而基本名称空间无关紧要,它已导入到其他子目录中,因此我还必须更新连接Web.Config内部的三个位置的字符串,以包含不同的子目录命名:


1

当项目移到解决方案根目录时,我的解决方案存在一个问题,该项目包含在解决方案文件夹中(以解决由于项目位置而导致的Mvc3AppConverter的可疑错误)。

尽管根据需要重新添加了所有项目参考之后编译的解决方案,但在启动网站时引发了该错误。

EDMX位于其中一个已移动的项目(“数据”项目)中,但是当然,缺少对数据项目的引用并不会导致编译错误,而只会导致运行时错误。

只需将缺少的引用添加到主项目即可解决此问题,而无需完全编辑连接。

我希望这可以帮助其他人。


1

对于我来说,我已经将数据访问层和用户界面层分开了。所以我有每一层的实体连接字符串。

在将这两个分开的连接字符串修改为相同之前,我仍然发现以下错误。

Unable to load the specified metadata resource

因此,对于这两个层(DAL,UI),我将其设为相同的连接字符串,它可以完美工作。

我的解决方案是使所有连接字符串都相同,无论它们在何处出现


1

昨天我遇到了这个问题,正在查看调试中的代码以及SQL Profiler的输出。

在阅读和理解这篇文章之前,我不明白的是为什么EntityFramework在调用数据库时抛出此错误。我在SQL Profiler中浏览了数百行,试图找出数据库模型出了什么问题。我找不到我所期待的电话,说实话,我不确定自己在寻找什么。

如果您在这个位置,请检查连接字符串。我的猜测是,在EntityFramework创建其SQL之前,它将检查在连接字符串的元数据部分中指定的模型。就我而言,这是错误的。EntityFramework甚至还没有达到DB。

确保名称正确。一旦解决了这个问题,便可以在SQL事件探查器中看到ApplicationName为'EntityFramework'的调用,其中SQL调用了期望的表。


1

不良的app.config或web.config文件可以执行此操作。.我已将app.config连接字符串复制到UI中的web.config中,并最终输入:

<connectionStrings>
    <connectionStrings>
          <add name="name" connectionString="normalDetails"/>
    </connectionStrings>
</connectionStrings>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.