ChatGPT解决这个技术问题 Extra ChatGPT

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

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

有人有想法么?

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

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

如果某个特定产品的浏览量超过 20 万的问题,那么该产品就没有按照用户期望的方式运行。我希望看到微软解决这个问题。如果您有时间,可以通过以下链接向他们提供建议:visualstudio.uservoice.com/forums/121579-visual-studio
通过替换从 db-layer 项目复制的连接字符串,我的问题解决了。
我也面临这个问题,我只是清理并重建工作正常的解决方案。
Marquis de Sade 活得很好,在微软工作。这真的是实体框架的地狱。
请参阅已接受答案下的评论。最后它只是一个不正确的连接字符串。

S
Stephen Turner

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

您可能已将模型的 MetadataArtifactProcessing 属性更改为复制到输出目录。

连接字符串可能是错误的。我知道您说您没有更改它,但是如果您更改了其他内容(例如,程序集的名称),它仍然可能是错误的。

您可能正在使用后编译任务将 EDMX 嵌入程序集中,但由于某种原因它不再工作。

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

更新:我写了 a blog post with more complete steps for troubleshooting


尽管我上次努力将其与内容比较实用程序进行比较,但连接字符串是错误的。
这也是我的连接字符串。当您的集成测试也需要在其自己的 App.config 中进行连接时,当您更新 edmx 时,事情可能会不同步。
好的,我通过简单地设置“嵌入”来修复它;编译,然后将其重置为另一个。这解决了我的问题。
如果它是连接字符串,并且您正在执行“DB first”,那么您可以通过将在 edmx 设计器中“从数据库更新”时获得的内容与 web.config 中的内容进行比较来轻松判断(在大多数情况下)或 app.config。
很棒的指南。对我来说,当我真的想要 res://*/MyModel1... 时,我复制了另一个使用 res://*/Database.MyModel2... 的连接字符串(数据库是我的集成测试项目中的一个文件夹)
S
SharpC

一个小的修改帮助我解决了这个问题。

我有一个包含 3 个项目参考的解决方案:

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

我改为:

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

它为我修复了它,但这到底是什么意思?
@Lance:我在 this blog post 中详细解释了这一点
@jocull:不,它在很多情况下都不起作用,在其他情况下会很慢。阅读我的博客文章以了解原因。
将我的 .edmx 移动到模型文件夹并忘记更新连接字符串。伟大的指针。谢谢。我要花几个小时才能弄清楚。
我已经完成了,id 解决了一个问题,但给了我另一个 All artifacts loaded into an ItemCollection must have the same version. Multiple versions were encountered. - 最后是 Npgsql。只有完整路径解决了这两个问题。
u
user276695

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


如果您在程序集中使用命名空间,请考虑“YourEdmxFileName”必须是限定名称,例如“YourNamespace.YourEdmxFileName”。但是,您必须删除与程序集名称相同的命名空间部分。
MSDN says the second paragraph is wrong.“当您使用通配符 (*) 时,实体框架必须在所有程序集中查找具有正确名称的资源。”
我很确定命名空间不相关,但嵌入的文件路径是相关的。因此,即使您检查关联 edmx 文件的 *.Designer.cs 文件并注意到自动生成的类命名空间是 MyCompany ......无论如何,这不是您应该使用的。相反,路径是程序集名称、解决方案文件夹名称/文件名。例如:“metadata=res://*/EntityModels..csdl|” + "res://*/EntityModels.<文件名>.ssdl|" + "res://*/EntityModels.<文件名>.msl;"
@Daniel,这基本上是正确的,但请注意命名空间和嵌入的文件路径有时是相同的。您必须查看 Reflector(或免费的替代品)才能确定。
看起来它只使用程序集名称,没有版本、publickeytoken 等。比如:res://MyAssembly/folder.<filename>.csdl...
q
qakmak

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

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

对此:

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

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


我将我的实体框架模型从模型移到了 DAL。但是后来当我在测试项目中写了一个测试(一周后)来测试Linq predicatebuilder。我得到了这个错误。我用它在主项目的 web.config 中的外观更正了测试项目 App.config - 正如你在三个地方所说的那样。所以你简单的回答让我走上了正轨。
两者有区别吗?!
@ErwinRooijakkers 模型与模型
在阅读 Craig 的博客后发现我做了同样的事情,但是 +1 学习重要的是要记住,在“实体”类库中所做的更改不会自动在引用它的项目的配置文件中进行。 /sigh 很高兴我并不孤单。
l
leqid

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

...obj/{配置输出}/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;)。


这正是我的问题。为此浪费了几个小时。非常感谢您的简单解释
很好的答案,实际上解释了如何找到你的字符串。并显示子文件夹有 '.'作为分隔符而不是“\”或“/”。
G
Ghlouw

我也遇到了这个问题,这是因为我的 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 字符串(注意末尾的细微差别 - 而不是它想要“application name=EntityFramework”的“App=EntityFramework”)复制到 web.config 中,问题就解决了。 :)


谢谢,这确实是我的问题。我有一个使用 EF 访问数据库的项目和另一个项目 WCF。更改第一个项目的名称后,我的第一个项目的 App.config 中的 connectionString 已更改。所以我不得不在 web.config 中更改项目 WCF 中的 connectionString :)
来自关于 docs.microsoft.com/en-us/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. Entity Framework 连接字符串不具备这种灵活性,因此您必须只使用它所期望的关键字。
L
Liakat Hossain

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

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

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


h
hgcummings

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


这是我的修复 - 我在复制时将 edmx 重命名为 .old 并尝试了一些操作,之后当我将其重命名为 Build Action 时,将其自身设置为 none 并因此出现此错误,将其设置回 EntityDeploy 已解决我的问题:)
我已将我的 EDMX 文件移动到另一个文件夹,并且必须更改构建操作以更新嵌入的资源名称。谢谢!
这就是我的解决方案;在升级到 .NET Standard 的过程中,我丢失了该设置。谢谢你拯救了我的理智!
这也是我的解决办法。必须设置与旧项目相同的 edmx 文件属性设置:EntityDeploy / Do not copy / EntityModelCodeGenerator
G
Graham Laight

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

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

...至...

metadata=res://*/DataModel.csdl

确实如此,如果要将其移动到新项目子文件夹中,则需要在其前面添加 folder.subfolder
谢谢,这个解决方案对我有用。我已将我的 .edmx 文件从一个项目中的目录移动到另一个项目的根目录,并且需要从我的解决方案中的所有连接字符串中删除目录名称。
T
TobyEvans

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

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


P
PiotrWolkowski

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


b
ben

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

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

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


+1,000,000 这是我今天的根本问题。重组产品命名空间和整合程序集的痛苦。
B
Basheer AL-MOMANI

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

如果您正在使用 n-tear architecture

或者您尝试将由 EDMX 生成的 separate Models 形成 DataAccessLayer 到 DomainModelLayer

也许你会得到这个错误

第一个故障排除步骤是确保 webconfig (UILayer) 和 appconfig (DataAccessLayer) 中的连接字符串相同第二个非常重要的连接字符串 connectionString="metadata=res://*/Model.csdl|res:// */Model.ssdl|res://*/Model.msl;provid.....这是问题所在

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

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

https://i.stack.imgur.com/zUv7L.png

希望对你有帮助


M
MOH3N

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

- 右键单击 EDMX 文件

- 选择 Run Custom Tool 选项

- 重建项目


这对我有用,但之后我也不得不重建
A
Adnan

我能够在 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 提出了修复模型路径的好方法。
b
ben

经过数小时的谷歌搜索并试图解决建议的解决方案都没有奏效。我在这里列出了几个解决方案。我还注意到对我有用的那个。 (我使用的是 EF 版本 6.1.1 和 SQL Server 2014 - 但使用的是较旧的数据库)

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

...以及我尝试过的更多[例如:将 EntityFramework 版本恢复到更高版本(不确定)]

什么对我有用:

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

解决方案资源管理器

右键单击文件 .edmx Open with.. Editor XML Change ProviderManifestToken="XXXX" with 2008

我希望这会有所帮助。


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

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


J
J. Steen

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

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

v1.0 BUG?: Unable to load the specified metadata resource. Scripts != Models

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


J
JWP

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

l
lau

当 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;
    }
}

R
Robocide

对于所有 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 

玩得开心。


K
Krishna shidnekoppa

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


A
Adam

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


A
Antoine Meltzheim

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

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

然后它工作得很好。


ص
صفي

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


不幸的是,它解决并治疗了症状,而不是原因。
e
eagle779

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


C
Chris

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

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

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

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

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


F
Frank Myat Thu

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

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

Unable to load the specified metadata resource

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

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


D
Daniel Hollinrake

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

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

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

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


M
MyDaftQuestions

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

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