突然,在实例化生成的ObjectContext类时,我一直得到一个MetadataException。App.Config中的连接字符串看起来是正确的-自从上次它工作以来没有改变-我已经尝试从底层数据库中重新生成一个没有变化的新模型(edmx-file)。
有人有什么想法吗?
进一步的细节:我没有更改任何属性,没有更改任何输出程序集的名称,也没有尝试将EDMX嵌入到程序集中。我只是下班后等了10个小时才回来。然后它就不管用了。
我试过重新创造EDMX。我试着重新创建这个项目。我甚至尝试从头开始重新创建数据库。不管怎样,运气不好。
我昨天遇到了这个问题,并在调试中查看了我的代码和SQL分析器的输出。
在我阅读和理解这篇文章之前,我不能理解的是,为什么EntityFramework在调用DB时抛出这个错误。我在SQL Profiler中查看了数百行,试图找出数据库模型的错误。我找不到我期待的那种电话,老实说,我也不确定我在找什么。
如果您处于此位置,请检查连接字符串。我的猜测是,在EntityFramework创建它的SQL之前,它会检查模型,在连接字符串的元数据部分指定。对我来说,这是错误的。EntityFramework甚至还没有到DB。
确保名字是正确的。一旦我得到了整理,我然后看到调用SQL Profiler的ApplicationName是'EntityFramework'与SQL调用预期的表。
在我的情况下,列出的答案没有一个是有效的,所以我发布了这个。
For my case, building on Visual studio and running it with IIS express worked fine. But when I was deploying using Nant scripts as a stand-alone website was giving errors. I tried all the suggestions above and then realized the DLL that was generated by the nant script was much smaller than the one generated by VS. And then I realized that Nant was unable to find the .csdl, .msl and .ssdl files. So then there are really two ways to solve this issue, one is to copy the needed files after visual studio generates them and include these files in the build deployment. And then in Web.config, specify path as:
"metadata=~/bin/MyDbContext.csdl|~/bin/MyDbContext.ssdl|~/bin/MyDbContext.msl;provider=System.Data.SqlClient;...."
这是假设您已经手动复制文件到您正在运行的网站的bin目录。如果它在不同的目录中,则相应地修改path。
第二种方法是在Nant脚本中执行EdmGen.exe,并生成文件,然后将它们作为资源,如下例所示:
https://github.com/qwer/budget/blob/master/nant.build
当Edmx在一个项目中,而您正在从另一个项目中使用它时,可以得到此异常。
原因是Res://*/是一个指向当前程序集中资源的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();
}
如果仍然遇到异常,请在reflector中打开程序集并检查.csdl、.ssdl和.msl文件的文件名。当资源与元数据值中指定的资源具有不同的名称时,将无法正常工作。