使用EF4的POCO模板时“找不到元数据信息”?

时间:2010-02-11 21:35:33

标签: entity-framework poco efpocoadapter

我刚为EF4安装了POCO模板。我的模型中有一个实体 AnnouncementText ,并且T4文件似乎已正确生成。当我访问自动生成的属性MyObjectContext.AnnouncementTexts时,尝试访问此新实体会引发以下错误:

  

InvalidOperationException:无法找到EntityType'MyNamespace.AnnouncementText'的映射和元数​​据信息。

AnnouncementText POCO上的属性似乎与数据库中的列匹配,并且我没有更改任何自动生成的代码。

堆栈跟踪是:

   at System.Data.Objects.ObjectContext.GetTypeUsage(Type entityCLRType)
   at System.Data.Objects.ObjectContext.GetEntitySetForNameAndType(String entitySetName, Type entityCLRType, String exceptionParameterName)
   at System.Data.Objects.ObjectContext.CreateObjectSet[TEntity](String entitySetName)
   at MyNamespace.MyObjectContext.get_AnnouncementTexts() in C:\<snip>\MyObjectContext.Context.cs:line 65
   at MyNamespace.Class1.Main() in C:\<snip>\Class1.cs:line 14

如果我从解决方案中删除.tt文件并在模型上启用代码生成,我可以毫无问题地访问该属性。

这是我的代码,如果可能有帮助:

using (var context = new MyObjectContext())
   foreach (var at in context.AnnouncementTexts)
      Console.WriteLine(at.Title);

关于可能出错的任何想法?

8 个答案:

答案 0 :(得分:27)

我最近在将EDMX文件移动到解决方案中的新位置时再次遇到同样的错误。显然,处理EDMX文件时有几个不同的命名空间。在创建初始EDMX文件(N1)时,通过向导输入了命名空间,另一个出现在SSDL中,看起来像这样(N2):

<Schema Namespace="..." ..

然后是生成的代码的命名空间,可以(可选)在设计器中指定(N3),最后有一些隐藏的资源名称空间被编译到最终的程序集中(N4)。

据我所知,命名空间 N2 仅在SSDL中真正相关。我相信这个命名空间以 N1 开始 - 你最初在向导中输入的那个。

同样,名称空间 N3 仅与C#名称空间通常相关。

这是有问题的部分。类别 N4 名称空间是您的EDMX所在的目录的函数(相对于您的项目目录) 。你可能会想,那又怎样?事实证明,这些命名空间也在App.config文件中引用!具体来说,寻找这样的部分:

connectionString="metadata=res://*/Database.Master.csdl|...

读取“Database.Master.csdl”的部分是您的CSDL资源的名称。如果这些资源名称不同步,您将收到类似上面的错误,或者可能是:

  

在地图和元数据信息中找不到指定的默认EntityContainer名称“[name]”。

简单的解决方案是更改App.config,为EF映射的每个部分(CSDL,SSDL和MSL)指定正确的资源名称。如果您不确定这些名称是什么,请在ILSpydotPeek中查看已编译程序集的资源。

答案 1 :(得分:4)

如果将EDMX文件复制到另一个项目,则“构建操作”(在“属性”窗格中)将恢复为目标项目中的默认值“无”,这可能导致“EntityContainer名称...无法成为发现“错误,这是因为没有生成资源。 (如果是这种情况,当您在Reflector中打开包含模型的DLL时,将没有资源。)将Build Action设置为“EntityDeploy”并重建解决方案将纠正此问题。

答案 2 :(得分:2)

不确定这个......看起来确实有点奇怪,所以这是一个很长的镜头。

但有时偶尔会有ObjectContext.MetadataWorkspace.LoadFromAssembly()调用。

即使没有,也会有第二个重载提供跟踪样式输出。

Assembly assembly = typeof(AnnouncementText).Assembly;
context.MetadataWorkspace.LoadFromAssembly(
    assembly, 
    (message) => Console.WriteLine(message)
);
foreach(var at in context.AnnouncementTexts)
   ...

看看你得到了什么消息(如果有的话)。

希望这有帮助

亚历

答案 3 :(得分:2)

在解决方案资源管理器中,右键单击实体数据模型文件(.edmx),然后单击“打开方式”。将打开一个对话框,选择一个程序供您打开文件。 选择或双击“XML(文本)编辑器”。

现在您要查看EDM文件的XML版本,您可以在其中轻松编辑“EntityContainer”名称。

如果您更改了webconfig文件中的连接字符串,请确保'DefaultContainerName'是该XML文件中'EntityContainer'部分的名称。

通常在更新* .Designer.cs文件中的defaultContainerName时,它不会更新XML文件。所以你手动完成。

答案 4 :(得分:1)

我通过在其中创建一个单独的项目和一个edmx来扩展NopCommerce。 POCO模板用于生成我的自定义ObjectContext后代类。

我验证了所有属性,所有命名空间,但仍然得到了上述异常。

重点是删除生成另一个ObjectContext后代类的 MyModel.Designer.cs 文件(另一个名称和另一个名称空间内)。

答案 5 :(得分:1)

我们使用没有edmx模型时遇到同样的问题,我们使用EF powertools beta 2,使用逆向工程代码第一个功能来生成我们的实体,上下文和视图。

我们有奇怪的行为,在几台机器上的团队中生成的编译视图的哈希是不同的,然后在TFS团队构建与其他机器上相同,我们得到如下的异常。问题是基于电动工具为编译视图生成哈希的内容?我们可以改变它是一致的,我们使用电源工具beta 2与EF 4.3.1,system.data .v4.0.30319,使用devart oracle驱动程序对Oracle数据库。

上下文生成视图

// --------------------------------------------- ---------------------------------

//

//此代码由工具生成。

//运行时版本:4.0.30319.551

//对此文件的更改可能会导致错误的行为,并且如果重新生成代码,则会丢失。

//

// --------------------------------------------- ---------------------------------

[assembly:System.Data.Mapping.EntityViewGenerationAttribute(typeof(Edm_EntityMappingGeneratedViews.ViewsForBaseEntitySetsC6473E0A11A196A36CC5839589DE2DE553F202E361016A89F2142797168B2534))]

命名空间Edm_EntityMappingGeneratedViews

{

/// <Summary>

/// The type contains views for EntitySets and AssociationSets that were generated at design time.

/// </Summary>

public sealed class ViewsForBaseEntitySetsC6473E0A11A196A36CC5839589DE2DE553F202E361016A89F2142797168B2534 : System.Data.Mapping.EntityViewContainer

{

    /// <Summary>

    /// The constructor stores the views for the extents and also the hash values generated based on the metadata and mapping closure and views.

    /// </Summary>

    public ViewsForBaseEntitySetsC6473E0A11A196A36CC5839589DE2DE553F202E361016A89F2142797168B2534()

    {

        this.EdmEntityContainerName = "Context";

        this.StoreEntityContainerName = "CodeFirstDatabase";

        this.HashOverMappingClosure = "2c6bbce22db7c9c65f8a70c5a1bae1225522a2124aad50e74bdc186ce8c70508";

        this.HashOverAllExtentViews = "26cad9d7334571a0116f89413345d00ec8e031706228df6e653c7b6396c94591";

        this.ViewCount = 56;

    }

例外:

System.Data.EntityCommandCompilationException:System.Data.EntityCommandCompilationException:准备命令定义时发生错误。有关详细信息,请参阅内部异常---&GT; System.Data.MappingException:EntityContainer'Context'的映射和元数​​据信息不再与用于创建预生成视图的信息匹配..

答案 6 :(得分:1)

在整合各种项目时,我遇到了类似的问题 问题是我有很多edmx,因为我有很多项目。

连接字符串相同,但名称空间不同。

要解决此问题,请选择一个要使用的连接并更改其他连接 请注意,您需要在designer.cs和xml文件中进行更改。

答案 7 :(得分:0)

更改视图sql后出现类似问题。必须右键鼠标在tt文件上更新它并修复它。