突然之间,我在实例化生成的 ObjectContext
类时不断收到 MetadataException
。 App.Config 中的连接字符串看起来是正确的——自上次工作以来没有改变——我尝试从底层数据库重新生成一个新模型(edmx 文件),没有任何变化。
有人有想法么?
更多细节:我没有更改任何属性,我没有更改任何输出程序集的名称,我没有尝试在程序集中嵌入 EDMX。我从下班到回来只等了10个小时。然后它不再工作了。
我试过重新创建 EDMX。我已经尝试重新创建该项目。我什至尝试从头开始重新创建数据库。没有运气,无论如何。
这意味着应用程序无法加载 EDMX。有几件事会导致这种情况。
您可能已将模型的 MetadataArtifactProcessing 属性更改为复制到输出目录。
连接字符串可能是错误的。我知道您说您没有更改它,但是如果您更改了其他内容(例如,程序集的名称),它仍然可能是错误的。
您可能正在使用后编译任务将 EDMX 嵌入程序集中,但由于某种原因它不再工作。
简而言之,您的问题中没有足够的细节来给出准确的答案,但希望这些想法能让您走上正轨。
更新:我写了 a blog post with more complete steps for troubleshooting。
一个小的修改帮助我解决了这个问题。
我有一个包含 3 个项目参考的解决方案:
connectionString="metadata=res://*/Model.Project.csdl|res://*/Model.Project.ssdl|res://*/Model.Project.msl;
我改为:
connectionString="metadata=res://*/;
All artifacts loaded into an ItemCollection must have the same version. Multiple versions were encountered.
- 最后是 Npgsql。只有完整路径解决了这两个问题。
当 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 文件的文件名。当资源的名称与元数据值中指定的名称不同时,它将不起作用。
res://MyAssembly/folder.<filename>.csdl...
我有一个类似的错误。我重新创建了这个项目(长篇大论),并从旧项目中提取了所有内容。我之前没有意识到我的模型在一个名为“Model”的目录中,现在在一个名为“Models”的目录中。一旦我从这里更改了我的 Web.Config 中的连接:
<add name="RecipeManagerEntities" connectionString="metadata=res://*/Model.Recipe.csdl
对此:
<add name="RecipeManagerEntities" connectionString="metadata=res://*/Models.Recipe.csdl
一切正常(将 Model
更改为 Models
)。请注意,我必须更改此字符串中的这三个位置。
还有一种快速检查没有反射器的模型名称的方法....查找目录
...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;)。
我也遇到了这个问题,这是因为我的 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="data source=SANDIEGO\sql2008;initial catalog=SCMS;integrated security=True;multipleactiveresultsets=True;application name=EntityFramework"" 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="data source=SANDIEGO\sql2008;initial catalog=SCMS;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
解决它的方法是简单地将 app.config 字符串(注意末尾的细微差别 - 而不是它想要“application name=EntityFramework
”的“App=EntityFramework
”)复制到 web.config 中,问题就解决了。 :)
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 连接字符串不具备这种灵活性,因此您必须只使用它所期望的关键字。
当我在构建新的 .edmx 设计器之前不清理解决方案时,就会发生这种情况。因此,在构建新的 .edmx 设计器之前不要忘记清理解决方案。这有助于我跳过这个问题的更多问题。如果您是 Visual Studio 的新手,请在下方提供导航详细信息。
单击->构建->清理解决方案然后单击->构建->重建解决方案
希望这可以帮助。感谢大家
当我不小心将 edmx 文件的构建操作(出现在 IDE 的属性下)从“EntityDeploy”切换到“None”时,这发生在我身上。 EntityDeploy 为您填充元数据:请参阅 http://msdn.microsoft.com/en-us/library/cc982037.aspx
如果您使用的是来自不同项目的 edmx,则在连接字符串中,更改...
metadata=res://*/Data.DataModel.csdl
...至...
metadata=res://*/DataModel.csdl
folder.subfolder
。
我刚刚度过了愉快的 30 分钟。我重命名了实体对象,重命名了配置文件中的条目,但还有更多......您还必须更改对 csdl 的引用
很容易错过 - 如果你要重命名,请确保你得到了一切......
我有同样的问题。我用反射器查看了我编译的 dll,发现资源的名称不正确。我重命名了,现在看起来很好。
就我而言,它是通过更改 edmx 文件的属性来解决的。
打开 edmx 文件 右键单击 EDMX 设计器的任意位置选择属性 更新名为“元数据工件处理”的属性到“嵌入输出程序集”
这为我解决了问题。问题是,当容器试图找到元数据时,它找不到它。所以只需在同一个程序集中进行即可。如果您的 edmx 文件位于另一个程序集中,此解决方案将不起作用
我花了一整天的时间来解决这个错误
如果您正在使用 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
希望对你有帮助
有时我会在我的项目中看到这个错误。我解决了这个问题
- 右键单击 EDMX 文件
- 选择 Run Custom Tool
选项
- 重建项目
我能够在 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"
经过数小时的谷歌搜索并试图解决建议的解决方案都没有奏效。我在这里列出了几个解决方案。我还注意到对我有用的那个。 (我使用的是 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
我希望这会有所帮助。
就我而言,此问题与重命名模型的 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”的文件夹中。
最终的解决方案(即使在另外两台机器上重新创建数据库,以及 EDMX 和其他杂项)是不使用实体框架的第一版。期待在 .NET 4.0 中再次对其进行评估。
在再次遇到同样的问题并到处寻找答案后,我终于找到了遇到同样问题的人。似乎 Visual Studio 的向导未正确生成连接字符串,并且元数据资源的链接缺少重要路径。
v1.0 BUG?: Unable to load the specified metadata resource. Scripts != Models
2013-01-16 更新:已过渡到几乎完全使用 EF Code First 实践(即使使用现有数据库),此问题不再是问题。对我来说,这是一个可行的解决方案,可以减少自动生成的代码和配置造成的混乱,并增加我自己对产品的控制。
我的问题和解决方案,症状是相同的“无法加载指定的元数据资源”,但根本原因不同。我在解决方案中有 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="
data source=Q\DEV15;initial catalog=whatever;
user id=myuserid;password=mypassword;
multipleactiveresultsets=True;
application name=EntityFramework""
providerName="System.Data.EntityClient" />
当 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;
}
}
对于所有 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
玩得开心。
例外是因为编译器指向不存在的元数据,所以只需将 app.config
连接字符串复制到 Web.config
连接字符串
我遇到了同样的错误消息。我的问题通过关闭并重新打开 Visual Studio 2010 得到解决。
有同样的问题,因为我重命名了一个程序集。
我还必须在项目 Properties/AssemblyInfo.cs 中的 AssemblyTitle 和 AssemblyProduct 属性中重命名它,并删除并重新添加对 edmx 文件的引用。
然后它工作得很好。
遇到同样的问题,我从数据库重新创建了 edmx。解决了我的问题。
我也有与 Rick 相同的问题和解决方案,除了我将现有的 .edmx 导入到新项目中,虽然基本命名空间无关紧要,但它被导入到不同的子目录中,所以我还必须更新连接Web.Config 中三个位置的字符串,以包含不同的子目录命名:
我在解决方案文件夹中包含项目的解决方案中遇到了同样的问题,当它们被移动到解决方案根目录时(为了克服由于项目位置而导致的 Mvc3AppConverter 的可疑错误)。
虽然根据需要重新添加了所有*项目引用后编译的解决方案,但在启动网站时抛出了错误。
EDMX 位于已移动的项目之一(“数据”项目)中,但当然,缺少对数据项目的引用不会导致编译错误,只是运行时错误。
只需添加对主项目的缺失引用即可解决此问题,根本无需编辑连接。
我希望这对其他人有帮助。
至于我,我已经分离了数据访问层和用户界面层。所以我有每一层的实体连接字符串。
在我将这两个单独的连接字符串修改为相同之前,我仍然发现以下错误。
Unable to load the specified metadata resource
所以我为这两层(DAL,UI)设置了相同的连接字符串,它工作得很好。
我的解决方案是使所有连接字符串都相同,无论它们已经出现在哪里。
我昨天遇到了这个问题,正在调试中查看我的代码和 SQL Profiler 的输出。
在我阅读并理解这篇文章之前,我无法理解的是,为什么 EntityFramework 在调用数据库时会抛出这个错误。我正在查看 SQL Profiler 中的数百行代码,试图找出数据库模型出了什么问题。我找不到任何像我期待的电话一样的东西,老实说,我不确定我在寻找什么。
如果您处于此位置,请检查连接字符串。我的猜测是,在 EntityFramework 创建其 SQL 之前,它会检查模型,在连接字符串的元数据部分中指定。就我而言,这是错误的。 EntityFramework 甚至没有达到数据库。
确保名称正确。一旦我把它整理好,我就会在 SQL Profiler 中看到调用,其中 ApplicationName 是“EntityFramework”,而 SQL 调用了预期的表。
一个糟糕的 app.config 或 web.config 文件可以做到这一点。我已将 app.config 连接字符串复制到我的 UI 中的 web.config 并最终输入:
<connectionStrings>
<connectionStrings>
<add name="name" connectionString="normalDetails"/>
</connectionStrings>
</connectionStrings>
不定期副业成功案例分享