EF 代码生成模板:发现差异?
Posted
技术标签:
【中文标题】EF 代码生成模板:发现差异?【英文标题】:EF code generation template: spot the difference? 【发布时间】:2015-05-25 11:56:57 【问题描述】:我前段时间使用旧的 ObjectContext 模板创建了一个 EF 项目(首先是 DB)。这会将所有内容生成一个巨大的 honkin' 文件。这样做有一些缺点,比如如果我想查看文件,IDE 需要一段时间才能将其全部加载到内存中,而修改需要一段时间才能刷新。另外,在源代码控制历史记录中很难一目了然:如果我想知道发生了什么变化,我必须在一个巨大文件的两个版本之间进行文件差异,而不是简单地查看孤立文件中的变化,生成为每班一个。
所以我决定尝试创建一个代码模板来生成相同代码,每个类只有一个文件。而且我认为我做得很好,因为代码编译得很好......但是当我打开应用程序时,我得到一个错误:
指定的架构无效。错误:
关系“AssessmentSchool”的属性包含角色“Assessment”,其类型“SchoolManagement.BL.Assessment”对关系结束无效。将 End Role 更改为 EntityType。
关系“AssessmentSchool”的属性包含角色“School”,其类型“SchoolManagement.BL.School”对关系结束无效。将 End Role 更改为 EntityType。
然后它继续列出系统中的每个多对多交集表(两次;关系的每一端一个)。在AssessmentSchool
的情况下,该表只有一个AssessmentID
和一个SchoolID
。
于是我对比了旧MyContext.designer.cs
中的关系声明,找到了任何提到关系的地方,并与新代码进行了对比。你能看出区别吗?
旧数据上下文:
[assembly: EdmRelationshipAttribute("SchoolManagement.BL", "AssessmentSchool", "Assessment", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(SchoolManagement.BL.Assessment), "School", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(SchoolManagement.BL.School))]
新的数据上下文:
[assembly: EdmRelationshipAttribute("SchoolManagement.BL", "AssessmentSchool", "Assessment", RelationshipMultiplicity.Many, typeof(SchoolManagement.BL.Assessment), "School", RelationshipMultiplicity.Many, typeof(SchoolManagement.BL.School), false)]
(是的,有一些小的区别:新文件在文件顶部有一个using System.Data.Metadata.Edm
语句,而isForeignKey
参数的false
无论如何都是默认值。我尝试手动删除它参数,它没有任何区别。)
OLD 评估类:
[XmlIgnoreAttribute()]
[SoapIgnoreAttribute()]
[DataMemberAttribute()]
[EdmRelationshipNavigationPropertyAttribute("SchoolManagement.BL", "AssessmentSchool", "School")]
public EntityCollection<School> Schools
get
return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<School>("SchoolManagement.BL.AssessmentSchool", "School");
set
if ((value != null))
((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<School>("SchoolManagement.BL.AssessmentSchool", "School", value);
新的评估课程:
[XmlIgnoreAttribute()]
[SoapIgnoreAttribute()]
[DataMemberAttribute()]
[EdmRelationshipNavigationPropertyAttribute("SchoolManagement.BL", "AssessmentSchool", "School")]
public virtual EntityCollection<School> Schools
get
return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<School>("SchoolManagement.BL.AssessmentSchool", "School");
set
if ((value != null))
((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<School>("SchoolManagement.BL.AssessmentSchool", "School", value);
对称关系在Class
类中也有,这里不再赘述。
这段代码看起来和我一模一样,它编译得很好,但它只是抛出了上面的运行时错误。显然,我在某个地方还缺少另一个技巧。但是什么?
【问题讨论】:
您发布的代码似乎是相同的。我的猜测是差异在另一个地方。我的建议是手动分解生成的单体代码,看看它是否有效,然后比较每个文件。我的猜测是关系在某个不明显的地方变得一团糟。 【参考方案1】:发现问题:我正在生成没有装饰器的 EntityObject
类:
[EdmEntityTypeAttribute(NamespaceName="SchoolManagement.BL", Name="Assessment")]
[Serializable()]
[DataContractAttribute(IsReference=true)]
public partial class Assessment : EntityObject
...
【讨论】:
接受您自己的答案,以便正确过滤问题。很高兴你解决了!以上是关于EF 代码生成模板:发现差异?的主要内容,如果未能解决你的问题,请参考以下文章
使用T4模板为EF框架添加实体根据数据库自动生成字段注释的功能