【问题标题】:EF Build self relationshipEF 建立自我关系
【发布时间】:2012-03-18 15:49:07
【问题描述】:

这次我有一个简单的问题:

我有一张桌子,和自己有关

=====================
| Id                |  
| IdParent          |
| NodeName          | 
=====================

IdParent 可以有 0 个或多个 Id。 问题是,我如何使用 FluentApi 或数据注释来配置这种关系。

这种关系的结果是一棵树(有两个层次),如下所示:

a
|---b
|---c 
d
e
f---g    

其中 (a,d,e,f) 是父节点,(b,c,g) 是子节点。

非常感谢您的帮助。

【问题讨论】:

    标签: entity-framework


    【解决方案1】:

    实体框架支持自引用外键。目前尚不清楚您是数据库第一人还是代码第一人。

    如果您是数据库第一人,只需在您的数据库中创建一个自引用外键,从数据库中更新模型。 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. 
    

    为了获得“零或 parentID”,您需要在表中包含一个包含零作为 ID 的条目。为什么?因为外键需要链接到 something。但是,我怀疑您想要的是使 IdParent 可以为空。您的问题没有指定数据库,但大多数主要数据库仅在有值时才强制执行外键。换句话说,IdParent 中的 Null 表示没有父级。

    【讨论】:

    • 感谢您的帮助。我的应用程序首先是 db。有什么办法可以用流畅的 API 做到这一点?
    • 对不起.. 链接(参见此处的示例)。效果很好。
    • @EBarr,嘿,别粗鲁;-o
    【解决方案2】:

    经过多次尝试.. 最佳解决方案是从此处为 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);
    }
    

    【讨论】:

      猜你喜欢
      • 2020-02-12
      • 2014-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-26
      • 2012-01-04
      • 2020-04-06
      • 1970-01-01
      相关资源
      最近更新 更多