2017-06-20 69 views
0

我有一个跟踪所有者阶级之间关系的一类。树可能是无限的 - 在DB中,每条记录都有一个父ID,它是对同一个表的自引用。这个类基本上是这样的:采用扁平化的的SelectMany类树()

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列表?

+0

这是一棵树,或者有向图?树不能有无限的专利子循环。 – dasblinkenlight

+0

[这是需要树的解决方案](https://stackoverflow.com/a/11830287/335858)。它不适用于循环图,它不会删除重复项。 – dasblinkenlight

+0

ObjectRelation应该有一个父属性,然后向上导航图寻找一个重复的ID。或者在ObjectRelation上创建一个名为Parents的扩展方法,返回一个IEnumerable ,然后检查是否有任何Parents是有问题的孩子。 'if(x.Parents.Any(p => p.ObjectId == x.ObjectId))throw Exception();' –

回答

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();