这次我有一个简单的问题:
我有一张与自己有关的表
=====================
| Id |
| IdParent |
| NodeName |
=====================
IdParent 可以有0个或多个 Id 。 问题是,如何使用FluentApi或数据anotations配置此关系。
这种关系的结果是一棵树(有两个级别),如下所示:
a
|---b
|---c
d
e
f---g
其中(a,d,e,f)是父节点,(b,c,g)是子节点。
非常感谢您的帮助。
答案 0 :(得分:3)
实体框架支持自引用外键。目前尚不清楚您是数据库优先还是代码优先。
如果您是数据库第一人,只需在数据库中创建自引用外键,即可从数据库更新模型。 EF至少支持EF 4。
支持这种键从代码第一的角度来看,它可能有点棘手。如果您使用的是EF 4.x,则需要覆盖OnModelCreating
函数(请参阅example here)。如果您使用的是EF 5(来自.net 4.5 beta或2011年6月的CTP),那么this question会提供一些很好的指导。缺点是在您的模型上使用[ForeignKey("IdParent")]
属性。
无论哪种方式,您都应该看到类似XML的内容......
<edmx:Runtime>
<edmx:StorageModels>
<Schema Namespace="...">
<AssociationSet Name="FK_Culture_has_ParentCulture"
Association="AL_Model.Store.FK_Culture_has_ParentCulture">
<End Role="Culture" EntitySet="Culture" />
<End Role="Culture1" EntitySet="Culture" />
</AssociationSet>
.....
.....
<edmx:ConceptualModels>
<Schema Namespace="...">
<EntityContainer Name="..." >
<Association Name="FK_Culture_has_ParentCulture">
<End Role="Culture" Type="AL_Model.Store.Culture" Multiplicity="0..1" />
<End Role="Culture1" Type="AL_Model.Store.Culture" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="Culture">
<PropertyRef Name="CultureID" />
</Principal>
<Dependent Role="Culture1">
<PropertyRef Name="ParentCultureID" />
</Dependent>
</ReferentialConstraint>
</Association>
自我参考结构
这句话引起了一些注意:
Where IdParent Could Have 0 or many Id.
为了拥有“零或父ID”,您需要在表中包含一个包含零作为ID的条目。为什么?因为外键需要链接到某些东西。但是,我怀疑你想要的是使IdParent可以为空的。您的问题未指定数据库,但大多数主要数据库仅在存在值时才强制执行外键。换句话说,IdParent中的Null表示没有父母。
答案 1 :(得分:1)
经过多次尝试...最佳解决方案是从为此提供EBarr示例的第一个链接中提取的。
我的最后一个解决方案是:
将Icollection添加到我的表格中:
public partial class myTable
{
public myTable()
{
this.Ids= new HashSet< myTable >();
}
public decimal id {get;set;}
public decimal idParent {get;set;}
public string NodeName {get;set;}
public Icollection<myTable> Ids {get;set;}
}
然后使用Fluent Api
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<myTable>()
.HasMany(x => x.Ids)
.WithOptional()
.HasForeignKey(m => m.IdParent);
}