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

有人有什么想法吗?

进一步的细节:我没有更改任何属性,没有更改任何输出程序集的名称,也没有尝试将EDMX嵌入到程序集中。我只是下班后等了10个小时才回来。然后它就不管用了。

我试过重新创造EDMX。我试着重新创建这个项目。我甚至尝试从头开始重新创建数据库。不管怎样,运气不好。


当前回答

在将一个大的解决方案从源代码管理资源管理器的一个文件夹移动到另一个文件夹后,我得到了这个问题。我们没有把包文件夹检查到Team Foundation,所以我认为VS会自动下载包。这将我的EF表单v6.1.2升级到v6.1.3。

当我降级到最初的v6.1.2时,这个问题就消失了。

其他回答

我刚花了30分钟玩这个。我重命名了实体对象,重命名了配置文件中的条目,但还有更多…您还必须更改对CSDL的引用

很容易错过-如果您正在重命名,请确保您获得所有内容....

我从解决方案中的所有项目中删除了\bin和\obj文件夹,然后重新构建解决方案,它工作得很好

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

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

我编写了这个helper类,当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;
    }
}