2017-08-24 7 views
1

私は、フォルダ階層を返すストアドプロシージャからビルドされたメニューを持っています。プロシージャは、FolderID、Name、およびParentIDを返します。私のメニューリポジトリでは、私のフォルダのリストにForEach()を使用して、親フォルダに関連付けられたすべてのサブフォルダを追加します。Linqを使用して同じオブジェクト内の子である親を削除します

それは次のようになります。

folders = await _dbcontext.MenuFolders.FromSql("EXEC UserMenuFolders @p0", UserID) 
    .Select(x => new MenuFolder 
     { 
      FolderID = x.FolderID, 
      FolderName = x.FolderName, 
      SortOrder = x.SortOrder, 
      SubofID = x.SubofID 
     })  
    .ToListAsync(); 

folders.ForEach(x => x.SubFolders = folders 
    .Where(y => y.SubofID == x.FolderID) 
    .OrderBy(y => y.SortOrder) 
    .ToList()); 

これは私のビットのように見えるオブジェクト与えます:

"Folder 1": { 
    "Sub Folder 1": [ 
     "SubFolder 1.1", 
     "SubFolder 1.2" 
    ], 
    "Sub Folder 2": [ 
     "SubFolder 2.1", 
     "SubFolder 2.2" 
    ] 
}, 
"Folder 2": { 
    //Other sub Folders 
}, 
"SubFolder 1":{}, 
"SubFolder 1.1":{}, 
"SubFolder 1.2": {} 

あなたが最初のクエリがを取得するため、サブフォルダ二回そこにあることがわかりますがすべてのフォルダ。サブフォルダであるフォルダをリストから削除するにはどうすればよいですか?また、私はこのメニュー構造を作成するより効率的な方法があるかどうかを知ることに興味がありますが、認可ロジックが既にそこに構築されているため、ストアドプロシージャを使用しなければならなかったことに留意してください。以下は

folders.RemoveAll(x => x.SubFolders.Any(c=> c.FolderID == x.FolderID)); 

そして、私のMenuFoldersエンティティは次のとおりです:

public int FolderID { get; set; } 
public string FolderName { get; set; }   
public int ParentID { get; set; } 
[ForeignKey("ParentID")] 
public List<MenuFolder> SubFolders { get; set; } 
public Int16 SortOrder { get; set; } 
+0

あなたのサンプルから削除したいのはどのSubFolder 1.1ですか?最初のものか2番目のものか? _ 'UserMenuFolders'のソースコードを含めてください。_ – mjwills

+0

2番目のファイルです。フォルダがForEachの後の子になった場合は、そのフォルダを削除します。 – Eric

答えて

2

あなたの試みと近かった

はここで何もしなかった私の微弱な試みです。基本的に、削除するものは子フォルダです。つまり、フォルダの親のIDがフォルダのIDとして存在する場合は、子のIDでなければならないため、安全に削除することができます。

folders.RemoveAll(x => folders.Any(f => f.FolderID == x.ParentID)); 
+1

うわー、私は自分自身を蹴っている!ありがとう@トラビス、それは働いた! – Eric

+1

これらの階層は、ときどき働くことに関係することができます。私は@Ericの前に同様のことをしました:) –

1

再帰を使用してください。

public static List<MenuFolder> ToTree(IEnumerable<MenuFolder> flatList, int parentId = 0) 
{ 
    var tree = flatList 
     .Where(m => m.ParentID == parentId) 
     .ToList(); 

    tree.ForEach(t => t.SubFolders = ToTree(flatList, t.FolderID)); 

    return tree; 
} 

そして、ちょうど戻る:

var foldersTree = ToTree(folders); 

注:ルートフォルダ(親なしフォルダ)ParentId == 0を持っていると仮定すると、あなたはこのようなものを使用することができ、これは任意の深さのツリー構造を作成します。

+0

それはかなりうまく@Federicoを動かしました。ありがとう! – Eric

+0

私の例では単純化のために2つのレベルしかないことにも留意してください。しかし、私のソリューションでは、あなたのような深さのツリーも作成されます。しかし、あなたのソリューションでは、私はRemoveAllメソッド呼び出しで行ったように脂肪をカットする必要はありません。素晴らしい答え、ありがとう! – Eric

関連する問題