715

突然间,我一直MetadataException在实例化我生成的ObjectContext类。App.Config 中的连接字符串看起来是正确的 - 自上次工作以来没有改变 - 我已经尝试从底层数据库重新生成一个新模型(edmx 文件)而没有任何变化。

有人有想法么?

更多细节:我没有更改任何属性,我没有更改任何输出程序集的名称,我没有尝试在程序集中嵌入 EDMX。我从下班到回来只等了10个小时。然后它不再工作了。

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

4

43 回答 43

874

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

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

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

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

于 2009-03-27T12:02:19.623 回答
381

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

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

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

改成

connectionString="metadata=res://*/;
于 2009-07-16T12:12:23.213 回答
116

当 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 文件的文件名。当资源的名称与元数据值中指定的名称不同时,它将不起作用。

于 2010-02-19T05:41:42.290 回答
70

我有一个类似的错误。我重新创建了这个项目(长篇大论),并从旧项目中提取了所有内容。我之前没有意识到我的模型在一个名为“Model”的目录中,现在在一个名为“Models”的目录中。一旦我从这里更改了我的 Web.Config 中的连接:

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

对此:

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

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

于 2009-12-04T05:55:00.033 回答
27

还有一种快速检查没有反射器的模型名称的方法....查找目录

...obj/{配置输出}/edmxResourcesToEmbed

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

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

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

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

于 2013-11-13T16:57:43.630 回答
17

我也遇到了这个问题,这是因为我的 web.config 中的连接字符串与我的 EDMX 所在程序集的 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" />

网络配置:

<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 中,问题就解决了。:)

于 2012-11-27T09:02:33.477 回答
17

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

点击->构建->清理解决方案

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

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

于 2018-06-25T01:48:56.963 回答
16

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

于 2009-12-17T10:11:06.930 回答
10

如果您使用的是来自不同项目的 edmx,则在连接字符串中,更改...

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

...到...

metadata=res://*/DataModel.csdl
于 2018-01-24T16:39:29.910 回答
8

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

很容易错过 - 如果你要重命名,请确保你得到了一切......

于 2010-01-12T16:37:10.807 回答
6

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

于 2009-10-12T09:42:25.387 回答
6

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

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

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

于 2010-10-02T09:09:32.580 回答
6

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

如果您正在使用n-tear architecture

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

也许你会得到这个错误

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

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

    这是问题所在

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

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

在此处输入图像描述

希望对你有帮助

于 2016-08-21T16:15:03.930 回答
6

有时我会在我的项目中看到这个错误。我解决了这个问题

1 - 右键单击​​ EDMX 文件

2 - 选择Run Custom Tool选项

3 - 重建项目

于 2018-08-06T05:06:31.327 回答
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"
于 2010-08-31T19:31:56.670 回答
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 版本恢复到更高版本(不确定)]


什么对我有用:

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

解决方案资源管理器

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

我希望这会有所帮助。

于 2015-07-29T10:27:25.713 回答
4

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

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

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

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

于 2009-04-20T16:45:44.310 回答
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" />
于 2014-09-29T16:23:42.767 回答
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”的文件夹中。

于 2010-06-23T07:44:40.747 回答
3

当 ObjectContext 对象在与使用它的项目不同的项目中定义时,我编写了这个帮助类来创建 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;
    }
}
于 2010-07-06T16:29:24.443 回答
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现在驻留在不同的程序集中(在 wcf 项目程序集中),

所以你应该替换YourObjectContextType.Assembly.FullName 为 -->

ClassTypeThatResidesInEdmProject.Assembly.FullName 

玩得开心。

于 2010-08-08T13:53:30.000 回答
3

例外是因为编译器指向不存在的元数据,所以只需将app.config 连接字符串复制到Web.config连接字符串

于 2016-07-12T12:28:08.883 回答
2

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

于 2011-05-23T12:29:26.377 回答
2

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

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

然后它工作得很好。

于 2012-03-29T15:28:29.553 回答
2

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

于 2013-10-22T13:17:57.673 回答
1

我也有与 Rick 相同的问题和解决方案,除了我将现有的 .edmx 导入到新项目中,虽然基本命名空间无关紧要,但它被导入到不同的子目录中,所以我还必须更新连接Web.Config 中三个位置的字符串,以包含不同的子目录命名:

于 2010-02-07T04:27:50.777 回答
1

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

虽然根据需要重新添加了所有*项目引用后编译的解决方案,但在网站启动时抛出了错误。

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

只需添加对主项目的缺失引用即可解决此问题,根本无需编辑连接。

我希望这对其他人有帮助。

于 2012-01-13T18:26:03.790 回答
1

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

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

Unable to load the specified metadata resource

所以我为这两层(DAL,UI)设置了相同的连接字符串,它工作得很好。

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

于 2012-11-02T02:59:59.863 回答
1

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

在我阅读并理解这篇文章之前,我无法理解的是,为什么 EntityFramework 在调用数据库时会抛出这个错误。我正在查看 SQL Profiler 中的数百行代码,试图找出数据库模型出了什么问题。我找不到任何像我期待的电话一样的东西,老实说,我不确定我在寻找什么。

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

确保名称正确。一旦我把它整理好,我就会在 SQL Profiler 中看到调用,其中 ApplicationName 是“EntityFramework”,而 SQL 调用了预期的表。

于 2014-03-20T08:21:54.723 回答
1

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

<connectionStrings>
    <connectionStrings>
          <add name="name" connectionString="normalDetails"/>
    </connectionStrings>
</connectionStrings>
于 2014-04-18T08:27:09.837 回答
1

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

于 2014-06-27T06:18:43.423 回答
1

使用此博文中的信息:

就像其他人所说的那样, res:\\ 是指向您的资源的指针。要检查并确保您的资源名称正确,您可以使用像JetBrains 的 DotPeek这样的反编译器来打开您的 .dll 文件并查看您的资源文件。

或者,您可以在调试时打开监视窗口并粘贴此代码以获取当前执行程序集中的资源名称数组。

System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames()

话虽如此,元数据路径的格式应该类似于:

{my-assembly-name}/{possibly-a-namespace}.{class-name}.{csdl or ssdl or msl}

于 2014-09-15T16:01:25.227 回答
1

只需键入路径而不是 {Path.To.The.}: res:// /{Path.To.The.}YourEdmxFileName.csdl|res:// /{Path.To.The.}YourEdmxFileName.ssdl| res://*/{Path.To.The.}YourEdmxFileName.msl

于 2016-02-12T19:31:03.220 回答
0

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

于 2010-02-16T17:10:19.623 回答
0

此异常的另一个原因是当您在 ObjectQuery 中包含相关表时,但键入了错误的导航属性名称。

例子:

var query = (from x in myDbObjectContext.Table1.Include("FKTableSpelledWrong") select x);
于 2010-09-29T14:30:35.120 回答
0

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

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

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

于 2011-08-10T15:52:34.133 回答
0

当我解决元数据问题时,我遇到了一个后续问题,即调用异常无法在 app.config 中找到 XXXEntities 的连接字符串(我的目标是不依赖于 app.config)。幸运的是,我发现在我的单元测试项目中引用 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 在模型文件夹。

于 2013-09-20T10:51:27.607 回答
0

对我来说类似的问题。我的班级名称与我的文件名不同。生成的连接字符串具有类名而不是文件名。对我来说,解决方案只是重命名我的文件以匹配类名。

于 2014-02-13T13:06:29.793 回答
0

当我的 emdx 文件被 prebuild 命令删除时,我收到了这个错误,很简单。我花了一段时间才意识到这很简单。

于 2016-02-09T15:05:13.787 回答
0

就我而言,这是因为我正在使用 EntityConnectionStringBuilder 构建连接字符串。确保您的元数据属性使用模型名称(包括命名空间)

于 2017-03-07T17:43:51.827 回答
0

将大型解决方案从源代码管理资源管理器中的一个文件夹移动到另一个文件夹后,我遇到了这个问题。我们不会将包文件夹检入 Team Foundation 中,因此我认为 VS 会自动下载包。这将我的 EF 表单 v6.1.2 升级到了 v6.1.3。

当我降级到原来的 v6.1.2 时问题就消失了。

于 2017-10-05T08:19:51.600 回答
0

在我的情况下,列出的答案都没有奏效,所以我发布了这个。

就我而言,在 Visual Studio 上构建并使用 IIS express 运行它运行良好。但是当我使用 Nant 脚本作为独立网站进行部署时,出现了错误。我尝试了上面的所有建议,然后意识到由 nant 脚本生成的 DLL 比 VS 生成的要小得多。然后我意识到 Nant 无法找到 .csdl、.msl 和 .ssdl 文件。那么实际上有两种方法可以解决这个问题,一种是在visual studio生成它们后复制所需的文件并将这些文件包含在构建部署中。然后在 Web.config 中,将路径指定为:

"metadata=~/bin/MyDbContext.csdl|~/bin/MyDbContext.ssdl|~/bin/MyDbContext.msl;provider=System.Data.SqlClient;...."

这是假设您已手动将文件复制到您正在运行的网站的 bin 目录中。如果它在不同的目录中,则相应地修改路径。第二种方法是在 Nant 脚本中执行 EdmGen.exe 并生成文件,然后将它们作为资源包含在下面的示例中: https ://github.com/qwer/budget/blob/master/nant.build

于 2018-05-24T19:42:28.520 回答
0

我在 2019 年 9 月 27 日遇到了同样的问题。

我的 API 在 Dot net core Targeting to .net 框架中。edmx 位于仅在 .net 框架中的不同类库中。

我观察到,当我尝试从 API 调用该 edmx 时 .. 出于某种原因,我收到了该错误。

我所做的是,转到 API 的 obj 文件夹并删除所有内容。然后清理 API 项目并重试,这对我有用。

于 2019-09-27T04:39:24.013 回答