2017-06-20 31 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; } 

} 

私のようにそれを確実にするために1つのリストのツリー内のすべてのユニークなIDのリストで終わるために、このクラスの単一のインスタンスへの参照を与えられた道が欲しい:クラスは、基本的にはこのようになりますユーザーは無限の親子ループを作成しないデータを入力しています(つまり、ID 1 & 2はお互いの親であります)。SelectManyが移動する方法のように見えます。そのようなクエリはLINQで実行可能ですか、または、ツリー全体を再帰的に処理し、子ノードがなくなると計算されたIDリストを返す別のメソッドを作成していますか?

+0

をこれは、ツリー、または有向グラフですか?木は無限の特許 - 子ループを持つことはできません。 – dasblinkenlight

+0

[こちらはツリーを必要とするソリューションです](https://stackoverflow.com/a/11830287/335858)。サイクルのあるグラフでは機能せず、重複は削除されません。 – dasblinkenlight

+0

ObjectRelationは親プロパティを持つ必要があります。次に、繰り返しIDを探してグラフを上に移動します。または、IEnumerable を返すParentsというObjectRelationの拡張メソッドを作成し、親が問題の子であるかどうかを確認します。 'if(x.Parents.Any(p => p.ObjectId == x.ObjectId))throw例外();' –

答えて

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(); 
関連する問題