使用 EF4 的 POCO 模板时“找不到元数据信息”?
Posted
技术标签:
【中文标题】使用 EF4 的 POCO 模板时“找不到元数据信息”?【英文标题】:"Metadata information not found" while using EF4's POCO Template? 【发布时间】:2011-01-15 21:57:32 【问题描述】:我刚刚为 EF4 安装了 POCO 模板。我的模型中有一个实体 AnnouncementText,并且 T4 文件似乎已正确生成。当我访问自动生成的属性MyObjectContext.AnnouncementTexts
时,尝试访问这个新实体会引发以下错误:
InvalidOperationException:找不到实体类型“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);
有什么想法可能是错的吗?
【问题讨论】:
您的项目中有多个 edmx 文件吗? 恐怕我只是添加了一个 edmx 来测试 iirc 的功能,尽管自从发布这个问题后我已经转移到 VS 2010 RC1。由于 POCO 模板才可用几天,我还没有机会查看我的问题是否仍然存在。 【参考方案1】:更改视图 sql 后遇到类似问题。必须在 tt 文件上右键才能更新它并修复它。
【讨论】:
【参考方案2】:在集成各种项目时,我遇到了类似的问题。
问题是我有不止一个edmx
,因为我有很多项目。
连接字符串相同,但命名空间不同。
要解决此问题,请选择要使用的连接之一并更改其他连接。请注意,您需要在 Designer.cs 和 xml 文件中进行更改。
【讨论】:
【参考方案3】:我们在不使用 edmx 模型时遇到了同样的问题,我们使用的是 EF powertools beta 2,使用逆向工程代码优先功能来生成我们的实体、上下文和视图。
我们有一个奇怪的行为,在几台机器上的团队中,生成的编译视图的哈希值是不同的,然后在 TFS 团队构建与其他机器上相同的情况下,我们会得到如下异常。问题是基于什么电动工具为编译视图生成哈希?并且我们可以更改它是一致的,我们使用带有 EF 4.3.1 的 power tools beta 2 , system.data .v4.0.30319 ,针对使用 devart oracle 驱动程序的 Oracle db。
上下文生成视图
//--------------------------------------------- ----------------------------------
//
//此代码由工具生成。
// 运行时版本:4.0.30319.551
// 对该文件的更改可能会导致不正确的行为,如果重新生成代码将丢失。
//
//--------------------------------------------- ----------------------------------
[程序集: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:准备命令定义时出错。有关详细信息,请参阅内部异常。 ---> System.Data.MappingException: EntityContainer 'Context' 的映射和元数据信息不再与用于创建预生成视图的信息匹配..
【讨论】:
【参考方案4】:我最近在将我的 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)的每个部分指定正确的资源名称。如果您不确定这些名称到底是什么,请查看 ILSpy 或 dotPeek 中已编译程序集的资源。
【讨论】:
太棒了,正是我想要的。我已将我的 edmx 文件移动到一个新文件夹中,实际上,EF 的元数据连接字符串中缺少的命名空间信息是罪魁祸首。谢谢! 在将我的数据库代码从它自己的文件夹重构到它自己的类库后,我收到错误“无法加载指定的元数据资源”。这个答案解释并解决了这个问题。谢谢!【参考方案5】:在解决方案资源管理器中,右键单击实体数据模型文件 (.edmx),然后单击“打开方式”。将打开一个对话框,让您选择一个程序来打开文件。 选择或双击“XML(文本)编辑器”。
现在您正在查看 EDM 文件的 XML 版本,您可以在其中轻松编辑“EntityContainer”名称。
如果您更改了 webconfig 文件中的连接字符串,请确保“DefaultContainerName”是该 XML 文件中“EntityContainer”部分的名称。
通常当您更新 *.Designer.cs 文件中的 defaultContainerName 时,它不会更新 XML 文件。所以你必须手动完成。
【讨论】:
【参考方案6】:我通过在其中创建一个单独的项目和一个 edmx 来扩展 NopCommerce。 POCO 模板用于生成我的自定义ObjectContext
后代类。
我验证了所有属性、所有命名空间,但仍然出现上述异常。
重点是删除 MyModel.Designer.cs 文件,该文件生成另一个 ObjectContext
后代类(具有另一个名称并位于另一个命名空间内)。
【讨论】:
【参考方案7】:如果您将 EDMX 文件复制到另一个项目,则构建操作(在“属性”窗格中)将恢复为目标项目中的默认值“无”,这可能导致“实体容器名称...无法找到”错误,这是因为没有生成资源。 (如果是这种情况,当您在 Reflector 中打开包含模型的 DLL 时,将没有资源。)将 Build Action 设置为“EntityDeploy”并重新构建解决方案将更正此问题。
【讨论】:
【参考方案8】:不确定这个......它看起来有点奇怪,所以这是一个很长的镜头。
但有时偶尔调用 ObjectContext.MetadataWorkspace.LoadFromAssembly() 会有所帮助。
即使没有提供跟踪样式输出的第二个重载。
即
Assembly assembly = typeof(AnnouncementText).Assembly;
context.MetadataWorkspace.LoadFromAssembly(
assembly,
(message) => Console.WriteLine(message)
);
foreach(var at in context.AnnouncementTexts)
...
然后看看你收到了什么消息(如果有的话)。
希望对你有帮助
亚历克斯
【讨论】:
好吧,在这种情况下,这似乎没有做(或打印)任何事情。我还尝试删除 POCO 的东西,并在您的示例代码中使用默认实体生成,恐怕在这种情况下我也没有看到任何输出。感谢您的尝试!在黑暗中拍摄是非常受欢迎的,呵呵。以上是关于使用 EF4 的 POCO 模板时“找不到元数据信息”?的主要内容,如果未能解决你的问题,请参考以下文章