协慌网

登录 贡献 社区

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

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

有人有主意吗?

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

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

答案

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

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

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

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

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

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

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

改成

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

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