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.这意味着如果你有一个Contentwith Id= x并且这个Content有一个ChildContentwith 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引用其他ChildContents并且不能有第二个Content引用相同的ChildContents(a的子代Content是唯一的,可以这么说)那么你就有一对多的关系.(这类似于订单和订单商品之间的关系:订单商品只能属于一个特定订单.)
映射ChildContent将如下所示:
modelBuilder.Entity<Content>()
.HasMany(c => c.ChildContent)
.WithOptional(); // or WithRequired()
Run Code Online (Sandbox Code Playgroud)
您将Content在数据库的表中有一个额外的外键列,该列属于此关联,但在实体类中没有相应的FK属性.
选项2b
如果许多Contents可以引用相同的ChildContents,那么你就有了多对多的关系.(这类似于用户和角色之间的关系:同一角色中可以有许多用户,用户可以拥有多个角色.)
映射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班级将有一个ChildContentRelationships 的集合:
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 次 |
| 最近记录: |