提问



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


有人有主意吗?


进一步的细节:我没有改变任何属性,我没有改变任何输出组件的名称,我没有尝试将EDMX嵌入到组件中。我只是等了10个小时才离开工作直到我回来。然后它就不再工作了。


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

最佳参考


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



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

  • 连接字符串可能有误。我知道你说你没有改变它,但如果你改变了其他东西(比如装配的名称),它可能仍然是错误的。

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



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


更新:我写了一篇博文,其中包含更完整的故障排除步骤。[43]

其它参考1


这个小改动有助于解决这个问题。


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


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


改成


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

其它参考2


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

其它参考3


我有类似的错误。我重新创建了这个项目(长篇故事),并从旧项目中删除了所有内容。我以前没有意识到我的模型已经在名为Model的目录中,现在位于名为Models的目录中。一旦我在Web.Config中更改了连接:


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


对此:


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


一切正常(改变ModelModels)。请注意,我必须在此字符串中更改这三个位置。

其它参考4


并且快速检查模型名称而不使用Reflector ....查找目录



  ... obj/{config output}/edmxResourcesToEmbed



并检查.csdl,.msl和.ssdl资源文件是否存在。如果它们位于子目录中,则必须将子目录的名称添加到模型名称之前。


例如,我的三个资源文件位于子目录数据中,因此我的连接字符串必须是



  元数据= RES://*/数据 .MyModel.csdl | RES://*/数据 .MyModel.ssdl | RES://*/数据 .MyModel.msl;



(与metadata=res://*/MyModel.csdl | res://*/MyModel.ssdl | res://*/MyModel.msl;)。

其它参考5


我也有这个问题,因为我的web.config中的连接字符串与我的EDMX所在的程序集的app.config中的连接字符串略有不同。不知道为什么会改变,但这里有两个不同的版本。


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" />


Web.config文件:


<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字符串(注意最后的小差异 - 而不是App=EntityFramework它想要application name=EntityFramework)进入web.config并解决了问题。 :)

其它参考6


当我意外地将edmx文件的构建操作(在IDE中的属性下显示)从EntityDeploy切换为None时,这发生在我身上。 EntityDeploy是为您填充元数据的内容:请参阅http://msdn.microsoft.com/en-us/library/cc982037.aspx [44]

其它参考7


我刚刚用这个花了30分钟。我重新命名了实体对象,重命名了配置文件中的条目,但还有更多...你还需要改变对csdl的引用


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

其它参考8


我能够在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"

其它参考9


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

其它参考10


对于我的情况,它通过更改edmx文件的属性来解决。



  1. 打开edmx文件

  2. 右键单击EDMX设计器的任何位置

  3. 选择属性

  4. 将名为元数据工件处理的属性更新为嵌入输出程序集



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

其它参考11


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


如果你正在n-tear architecture


或者你试图将EDMX生成的separate Models表格DataAccessLayer改为DomainModelLayer


也许你会得到这个错误



  1. 首先排除故障的步骤是确保webconfig (UILayer)appconfig (DataAccessLayer)中的连接字符串相同

  2. 第二个非常重要 connection string


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


    这是问题所在



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


在这里,我的解决方案看看图片


[45]


希望对你有所帮助

其它参考12


最终解决方案(即使在其他两台机器上重建数据库,以及EDMX和其他杂物)也不使用第一版的Entity Framework。期待在.NET 4.0中再次对其进行评估。


在遇到同样的问题再次并搜索到所有的答案后,我终于找到了一个有同样问题的人。看来连接字符串没有被Visual Studio正确生成向导,以及元数据资源的链接缺少一条重要的路径。


v1.0 BUG?:无法加载指定的元数据资源。脚本!=模型[46]


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

其它参考13


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

其它参考14


经过几个小时的谷歌搜索,并试图解决所有建议的解决方案。我在这里列出了几个解决方案。我也注意到了一个适合我的方法。 (我使用的是EF版本6.1.1和SQL Server 2014 - 但是使用的是较旧的数据库)



  1. 重建项目并重试。

  2. 关闭并打开VS - 我不知道这是如何工作的

  3. 确保您是否已将.EDMX文件放在目录中,请确保在ConnectionString中包含目录。例如我的是在DAL文件夹中。所以它看起来像这样:connectionString="metadata=res://*/DAL.nameModel.csdl|res://*/DAL.nameModel.ssdl|res://*/DAL.nameModel.msl;(这些是文件。看到它们你可以在解决方案资源管理器中切换显示所有文件,在〜/obj/..目录下)



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





对我有用的东西:


从这篇文章中,它帮助我解决了我的问题。我刚刚在EDMX文件中将ProviderManifestToken="2012"更改为ProviderManifestToken="2008"。为此:[47]


Solution Explorer



  1. 右键单击文件.edmx

  2. 以...打开

  3. 编辑XML

  4. 使用2008
  5. 更改ProviderManifestToken =XXXX


我希望有所帮助。

其它参考15


在我的情况下,这个问题与重命名我的模型的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的文件夹中。

其它参考16


我编写了这个辅助类来创建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;
    }
}

其它参考17


对于所有人SelftrackingEntities用户,
如果您已遵循Microsoft Walk-through并将Object上下文类分离为
wcf服务项目(通过链接到上下文.tt)所以这个答案适合你:


本文中显示的答案的一部分包括以下代码:


... = string.Format("res://{0}/YourEdmxFileName.csdl|res://{0}/YourEdmxFileName.ssdl|res://{0}/YourEdmxFileName.msl", 
        typeof(YourObjectContextType).Assembly.FullName); 


不会为你工作!!原因是YourObjectContextType.Assembly现在位于不同的Assembley(在wcf项目组件内),


所以你应该用 - >替换YourObjectContextType.Assembly.FullName


ClassTypeThatResidesInEdmProject.Assembly.FullName 


玩的开心。

其它参考18


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

其它参考19


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


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


然后它工作得很好。

其它参考20


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

其它参考21


例外是因为编译器指向不存在的元数据所以只需将app.config connectionstring复制到Web.config ConnectionString

其它参考22


我也有与Rick相同的问题和解决方案,除了我将现有的.edmx导入到一个新项目中,而基本命名空间并不重要,它被导入到一个不同的子目录中,因此我还必须更新连接Web.Config里面的三个字符串,包括不同的子目录命名:



其它参考23


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


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


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


只需将缺少的引用添加到主项目即可解决此问题,无需编辑连接。


我希望这有助于其他人。

其它参考24


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


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

其它参考25


我根本没有引用包含EDMX文件的类库。

其它参考26


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


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


...至...


metadata=res://*/DataModel.csdl

其它参考27


当我在构建新的.edmx设计器之前不清理解决方案时,这种情况发生在我身上。因此,在构建新的.edmx设计器之前,不要忘记清理解决方案。这有助于我跳过很多这个问题。提供导航详细信息,这是视觉工作室的新功能。



  单击 - >构建 - >清除解决方案

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



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

其它参考28


我的理论是,如果你有多个具有相同名称的edmx文件(例如Model1),它将给出该异常。
当我决定将所有edmx文件(坐在不同的项目中)命名为Model1时,我遇到了同样的问题,因为我认为它们应该是独立的。

其它参考29


此异常的另一个原因是在ObjectQuery中包含相关表,但键入错误的导航属性名称。


例:


var query = (from x in myDbObjectContext.Table1.Include("FKTableSpelledWrong") select x);