【问题标题】:EF6 Self Referencing Table with multiple parent properties, single child collection具有多个父属性、单个子集合的 EF6 自引用表
【发布时间】:2015-06-11 14:22:21
【问题描述】:

我有一个引用自身的表,但我正在努力获得所需的映射。我希望能够将孩子定义为具有特定人作为母亲、父亲和/或监护人的人的集合。监护人可以是父亲或母亲。

我想要一个可以在列出人员的位置浏览的人员树形视图;用户可以展开一个人的节点以显示该人的所有孩子,而不考虑孩子定义的关系(母亲、父亲或监护人)。

public partial class Person
{
    [Key]
    public int ID { get; set; }

    [StringLength(100)]
    public string Name { get; set; }


    public int? GuardianID { get; set; }

    [Column("MotherID")]
    public int? MotherID { get; set; }


    [Column("FatherID")]
    public int? FatherID { get; set; }

    [ForeignKey("MotherID")]
    public virtual tblPerson Mother { get; set; }

    [ForeignKey("FatherID")]
    public virtual tblPerson Father { get; set; }

    [ForeignKey("GuardianID")]
    public virtual tblPerson Guardian { get; set; }

    [InverseProperty("Guardian")]
    [InverseProperty("Father")]
    [InverseProperty("Mother")]
    public virtual IEnumerable<tblPerson> children { get; set; }
}

现在我的视图必须如下所示:

    @using Person_MVC.Models
    @model IEnumerable<Person>
    @{
        IEnumerable<Person> children;
    }

    <ul>
        @foreach (Person person in Model.OrderBy(p => p.PersonNumber))
        {
            <li id="Pnl_@Person.ID" data-jstree='{"type":"Person"}' data-Personkey="@Person.ID.ToString()">
                @Person.Name
                @{
            PersonModel db = new PersonModel();
            children = (from p in db.Persons where p.GuardianID == Person.ID || p.Father == Person.ID || p.MotherID == Person.ID select p).ToList();
                }
                @if (children != null && children.Count() > 0)
                {
                    @Html.Partial("PersonTree", children)
                }
            </li>
        }
    </ul>

【问题讨论】:

    标签: entity-framework data-annotations fluent self-referencing-table


    【解决方案1】:

    我想更好的解决方案是在您的模型中创建三个导航列表,并且可能有一种方法来连接对象以将所有儿子返回给您。

    例如

    public int? FatherId { get; set; }
    
    public int? GrandFatherId { get; set; }
    
    public int? MotherId { get; set; }
    
    public virtual ICollection<Person> FatherForThose { get; set; }
    public virtual Person Father { get; set; }
    
    public virtual ICollection<Person> GrandFatherForThose { get; set; }
    public virtual Person GrandFather { get; set; }
    
    public virtual ICollection<Person> MotherForThose { get; set; }
    public virtual Person Mother { get; set; }
    
    
    public ICollection<Person> GetChildren()
    {
        var list = FatherForThose.Concat(MotherForThose).ToList();
        foreach (var person in GrandFatherForThose)
        {
            if (list.All(i => i.Id != person.Id))
            {
                list.Add(person);
    
            }
        }
        return list;
    }
    

    但您应该始终注意将它们包含在您的查询中 例如

    var grand = context.Persons.Include(x => x.FatherForThose)
                .Include(x => x.GrandFatherForThose)
                .Include(x => x.MotherForThose)
                .FirstOrDefault(x => x.Id == 2);
    
    var list = grand.GetChildren();
    

    【讨论】:

      【解决方案2】:
      1. 所有表数据都应该在手(否则我们可能会多次调用数据库)。
      2. 查找所有没有父母的人的列表(即一个人没有监护人身份、母亲身份、父母身份)并从他们开始。

      【讨论】:

        【解决方案3】:

        试试这个也可以...

        public partial class Person
            {
                [Key]
                public int ID { get; set; }
        
                [StringLength(100)]
                public string Name { get; set; }
        
        
                public int? GuardianID { get; set; }
        
                [Column("MotherID")]
                public int? MotherID { get; set; }
        
        
                [Column("FatherID")]
                public int? FatherID { get; set; }
        
                public IEnumerable<Person> Children { get
                        {
                            return context.Person.Where(p => p.GuardianID == this.ID || p.Father == this.ID  || p.MotherID == this.ID).ToList();
                        } 
                }
            }
        
        
        
        
        
         @using Person_MVC.Models
            @model IEnumerable<Person>
        
            <ul>
                @foreach (Person person in Model.OrderBy(p => p.PersonNumber))
                {
                    <li id="Pnl_@Person.ID" data-jstree='{"type":"Person"}' data-Personkey="@Person.ID.ToString()">
                        @Person.Name
        
                        @if (Person.Children != null && Person.Children.Count() > 0)
                        {
                            @Html.Partial("PersonTree", Person.Children)
                        }
                    </li>
                }
            </ul>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-12-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-05
          相关资源
          最近更新 更多