使用SelectMany()展平类树

时间:2017-06-20 16:43:37

标签: c# linq tree

我有一个跟踪所有者类之间关系的类。树可能是无限的 - 在DB中,每个记录都有一个父ID,它是对同一个表的自引用。该课程基本上如下:

public class ObjectRelation
{

    public ObjectRelation(GetObjectParentChildList_Result relation)
    {
        this.ObjectId = relation.Object_ID;
        this.ParentObjectId = relation.Parent_Object_ID;
        this.ChildObjects = new List<ObjectRelation>();
    }

    public int ObjectId { get; set; }
    public int? ParentObjectId { get; set; }
    public List<ObjectRelation> ChildObjects { get; set; }

}

我想给出一个引用这个类的单个实例的方法,最终得到一个列表中树中每个唯一ID的列表,以确保当用户输入数据时他们不会创建一个无限的父/子循环(即,ID 1和2是彼此的父母),看起来好像是SelectMany。这样的查询在LINQ中是否可行,或者我是否一直在编写一个单独的方法来重新计算整个树并在用完子节点后返回计算出的ID列表?

1 个答案:

答案 0 :(得分:0)

public class ObjectRelation
{
    public ObjectRelation(GetObjectParentChildList_Result relation)
    {
        this.ObjectId = relation.Object_ID;
        this.Parent = relation.Parent_Object;
        this.ChildObjects = new List<ObjectRelation>();
    }

    public int ObjectId { get; set; }
    public ObjectRelation Parent { get; set; }
    public List<ObjectRelation> ChildObjects { get; set; }
}

public static class ObjectRelationExtensions
{
  public static IEnumerable<ObjectRelation> Parents(this ObjectRelation obj)
  {
    while(obj.Parent!=null)
    {
      obj = obj.Parent;
      yield return obj;
    }
  }
}

然后检查:

if (x.Parents.Any(p=>p==x)) throw Exception();

if (x.Parents.Any(p=>p.ObjectId==x.ObjectId)) throw Exception();