2017-11-08 9 views
0

asp.net c#+ EFを使用してparentChildオブジェクトでいくつかの入力が必要です。sql dbからのC#で親子ツリーを構築する

目的:

public class Organo 
{ 
    [Key] 
    public int id { get; set; } 
    public int key { get; set; } 
    public int parent { get; set; } 
    public string name { get; set; } 
    public string text { get; set; } 
    [NotMapped] 
    public List<Organo> OrganoChildrens { get; set; } 
} 

データ例:

id | key | parent | name | text 
----+-------+----------+--------+---------- 
1  1  0   A  A 
2  2  1   B  B 
3  3  1   C  C 
4  4  2   B1  B1 
5  5  4   B1_1 B1_1 
6  6  1   D  D 

マイコントローラASP.NET図

マイクラス(DBテーブル)への親と子供で構成オブジェクトを返します。

public async Task<ActionResult> index() 
{ 
     //get all data 
     var organos = await db.Organos.ToListAsync(); 

     Organo organo_ = new Organo(); 

     foreach (var item in organos) 
     { 
      //head of diagram 
      if(item.parent == 0) 
      { 
       organo_.id = item.id; 
       organo_.key = item.key; 
       organo_.parent = 0; 
       organo_.name = item.name; 
       organo_.text = item.text; 
      } 
      else 
      { 
       //child 
       Organo organoChild_ = new Organo(); 
       organoChild_.id = item.id; 
       organoChild_.key = item.key; 
       organoChild_.parent = item.parent; 
       organoChild_.name = item.name; 
       organoChild_.text = item.text; 
       organo_.OrganoChildrens.Add(organoChild_); 
      } 
     } 

     return View(fishbone_); 
} 

しかし、これで私は...私は親の階層を構築する方法を子どもたちの最初のレベルを取得する -

+1

再帰を使用して、親であるときに親の子をループします。 – reggaeguitar

+0

2番目のelse?いくつかのイデアを教えてください。 – user2633804

+0

ダイアグラムの頭部は1つだけですか? – reggaeguitar

答えて

0

この

ような何かを試してみてください> CHILD1のCHILD2 ....

多くの感謝 - > CHILD1

public async Task<ActionResult> index() 
    { 
      //get all data 
      var organos = await db.Organos.ToListAsync(); 
      var populatedOrgano = PopulateChildren(organos.Single(x => x.parent == 0)); 


      return View(populatedOrgano); 
    } 

    public Organo PopulateChildren(Organo sourceOrgano, ICollection<Organo> organos) 
    { 
     Organo organo_ = new Organo(); 
     var children = organos.Where(x => x.parent == sourceOrgano.id); 
     foreach (var child in children)     
     { 
      //child 
      Organo organoChild_ = new Organo(); 
      organoChild_.id = child.id; 
      organoChild_.key = child.key; 
      organoChild_.parent = child.parent; 
      organoChild_.name = child.name; 
      organoChild_.text = child.text; 
      organo_.OrganoChildrens = new List<Organo>(); 
      organo_.OrganoChildrens.Add(organoChild_); 
      PopulateChildren(child, organos); 
     } 
     return organo_; 
    } 
+0

私はこれをテストしていませんが、オルガノの新しくなったことで奇妙なことが起きるかもしれませんが、始めるには十分であるはずです。 – reggaeguitar

+0

ここにエラーが表示されます: organo_.OrganoChildrens.Add(organoChild_); >オブジェクト参照がオブジェクトのインスタンスに設定されていません。 – user2633804

+0

私の編集をチェックしてください。追加する前に、OrganoChildrensのリストを新しくする必要があります。 – reggaeguitar

0

まず、階層モデルのデータを表現するためのビューモデルが必要です(データモデルから[NotMapped]public List<Organo> OrganoChildrens { get; set; }プロパティを削除してください)。

public class OrganoVM 
{ 
    public int ID { get; set; } 
    public int Key { get; set; } 
    public string Name { get; set; } 
    public string Text { get; set; } 
    public List<OrganoVM> Children { get; set; } 
} 

null値ではなく実際には存在しない0)を使用するよりも、トップレベルのオブジェクトを意味するように私はまた、データベースのNULL可能で、あなたのparentフィールドを作るお勧めします。以下のコードはnullparentフィールドに基づいています。

次に、あなたはあなたが、その後

OrganoVM model = groups[null].FirstOrDefault(); 

を使用して(一つだけがあることを仮定して)「トップレベル」のオブジェクトを返すことができ、階層構造

// Sort and group the records 
var groups = db.Organos 
    .OrderBy(x => x.parent) 
    .ToLookup(x => x.parent, x => new OrganoVM 
    { 
     ID = x.id, 
     Key = x.key, 
     Name = x.Name, 
     Text = x.text 
    }); 

// Assign children 
foreach (var item in groups.SelectMany(x => x)) 
{ 
    item.children = groups[item.ID].ToList(); 
} 

を生成する.ToLookup().GroupBy()を使用することができます複数の「トップレベル」オブジェクト(parent = null)がある場合は、

List<OrganoVM> model = groups[null].ToList(); 

あなたのビューや階層データの表示方法は表示されていませんが、this answerに似たDOMを再帰的に構築する拡張メソッドHtmlHelperが考えられます。

関連する問題