Dea*_*lan 7 sql entity-relationship entity-framework ef-code-first entity-framework-4.1
我有一类内容,它应该能够有一个parentId用于继承,但我希望它有一个子内容列表,这与这个继承树无关.
我基本上想要一个链接表作为ChildContentRelationship与Id的parentContent和childContent在其中,Content类将有一个ChildContentRelationship列表.
这导致了很多错误.
我有点想做
public class Content
{
public int Id { get; set; }
public int? ParentContentId { get; set; }
public virtual Content ParentContent { get; set; }
public string Name { get; set; }
public int ContentTypeId { get; set; }
public virtual ContentType ContentType { get; set; }
public virtual ICollection<Property> Properties { get; set; }
public virtual ICollection<ChildContentRelationship> ChildContent { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我如何在EF中设置它?
Sla*_*uma 18
我不确定我是否正确理解你的模型.我们来讨论一下这些选项.
暂时我省略了这个额外的实体ChildContentRelationship
,我假设ChildContent
集合是类型的ICollection<Content>
.
选项1:
我认为ParentContent
是逆属性的ChildContent
.这意味着如果你有一个Content
with Id
= x并且这个Content有一个ChildContent
with Id
= y那么ChildContents ParentContentId
必须总是x.这只是一个关联,ParentContent
并且ChildContent
是同一关联的端点.
可以使用数据注释创建此关系的映射...
[InverseProperty("ParentContent")]
public virtual ICollection<Content> ChildContent { get; set; }
Run Code Online (Sandbox Code Playgroud)
...或使用Fluent API:
modelBuilder.Entity<Content>()
.HasOptional(c => c.ParentContent)
.WithMany(c => c.ChildContent)
.HasForeignKey(c => c.ParentContentId);
Run Code Online (Sandbox Code Playgroud)
我认为这不是你想要的("......与......无关").考虑重命名导航属性.如果有人读了Parent...
,Child...
他很可能会认为他们为同一个关系构建了一对导航属性.
选项2:
ParentContent
不是反向属性ChildContent
意味着您实际上有两个独立关系,并且两个关系的第二个端点未在模型类中公开.
映射ParentContent
将如下所示:
modelBuilder.Entity<Content>()
.HasOptional(c => c.ParentContent)
.WithMany()
.HasForeignKey(c => c.ParentContentId);
Run Code Online (Sandbox Code Playgroud)
WithMany()
不带参数表示第二个端点不是模型类中的属性,尤其不是 ChildContent
.
现在,问题仍然存在:什么样的关系ChildContent
属于什么?它是一对多还是多对多的关系?
选项2a
如果a Content
引用其他ChildContent
s并且不能有第二个Content
引用相同的ChildContent
s(a的子代Content
是唯一的,可以这么说)那么你就有一对多的关系.(这类似于订单和订单商品之间的关系:订单商品只能属于一个特定订单.)
映射ChildContent
将如下所示:
modelBuilder.Entity<Content>()
.HasMany(c => c.ChildContent)
.WithOptional(); // or WithRequired()
Run Code Online (Sandbox Code Playgroud)
您将Content
在数据库的表中有一个额外的外键列,该列属于此关联,但在实体类中没有相应的FK属性.
选项2b
如果许多Content
s可以引用相同的ChildContent
s,那么你就有了多对多的关系.(这类似于用户和角色之间的关系:同一角色中可以有许多用户,用户可以拥有多个角色.)
映射ChildContent
将如下所示:
modelBuilder.Entity<Content>()
.HasMany(c => c.ChildContent)
.WithMany()
.Map(x =>
{
x.MapLeftKey("ParentId");
x.MapRightKey("ChildId");
x.ToTable("ChildContentRelationships");
});
Run Code Online (Sandbox Code Playgroud)
此映射将ChildContentRelationships
在数据库中创建连接表,但您不需要此表的相应实体.
选项2c
只有在多对多关系除了两个键(ParentId
和ChildId
)之外还有更多属性的情况下(例如CreationDate
,RelationshipType
或者......),您必须ChildContentRelationship
在模型中引入一个新实体:
public class ChildContentRelationship
{
[Key, Column(Order = 0)]
public int ParentId { get; set; }
[Key, Column(Order = 1)]
public int ChildId { get; set; }
public Content Parent { get; set; }
public Content Child { get; set; }
public DateTime CreationDate { get; set; }
public string RelationshipType { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在你的Content
班级将有一个ChildContentRelationship
s 的集合:
public virtual ICollection<ChildContentRelationship> ChildContent
{ get; set; }
Run Code Online (Sandbox Code Playgroud)
你有两个一对多的关系:
modelBuilder.Entity<ChildContentRelationship>()
.HasRequired(ccr => ccr.Parent)
.WithMany(c => c.ChildContent)
.HasForeignKey(ccr => ccr.ParentId);
modelBuilder.Entity<ChildContentRelationship>()
.HasRequired(ccr => ccr.Child)
.WithMany()
.HasForeignKey(ccr => ccr.ChildId);
Run Code Online (Sandbox Code Playgroud)我相信你想要2a或2b选项,但我不确定.
归档时间: |
|
查看次数: |
7861 次 |
最近记录: |