0

如何選擇自引用表的所有級別作爲視圖模型。如果最高級別是2或3,那麼我可以通過多次調用Select來實現,但我有4-5級菜單,我認爲應該有更好的解決方案來做到這一點,並選擇所有級別。從自引用表中選擇並轉換爲視圖模型

這是我的視圖模型:

public class MenuViewModel 
{ 
    public MenuViewModel() 
    { 
     Childs = new HashSet<MenuViewModel>(); 
    } 

    public int Id{ get; set; } 
    public string Title { get; set; } 
    public string Url { get; set; } 

    public ICollection<MenuViewModel> Childs { get; set; } 
} 

,這是我的菜單類:

public class Menu 
{ 
    public Menu() 
    { 
     Childs = new HashSet<Menu>(); 
    } 

    public int Id{ get; set; } 
    public string Title { get; set; } 
    public string Url { get; set; } 
    public string Description { get; se; } 
    public byte[] Icon { get; set; } 
    public int Order { get; set; } 

    public ICollection<Menu> Childs { get; set; } 
} 

var viewModel = _dataContext.Menus 
.Select(x => new MenuViewModel 
{ 
    Id = x.Id, 
    Title = x.Title, 
    Child = ??? 
} 
.ToList(); 
+0

你的'菜單'是怎麼樣的? –

+0

@HariPrasad其幾乎像我的viewmodel –

+1

'菜單'包含子集合?你能舉一個例子說明它是如何自引用父母/孩子的嗎? –

回答

0

假設Id屬性是獨特的,你可以分兩次做到這一點:

  1. 創建沒有兒童的viewmodel項目,但帶有關聯的兒童id。從這些數據創建Dictionary,這將允許您通過其id獲取任何視圖模型。這個字典中的值將是創建的viewmodels以及他們的子id。
  2. 對於每個viewmodel項目,使用子標識符獲取關聯的視圖模型項目。

喜歡的東西:

var tempModels = _dataContext 
    .Menus 
    .Select(menu => new 
    { 
     childrenIds = menu.Childs.Select(item => item.Id).ToArray(), 
     viewModel = 
      new MenuViewModel 
      { 
       Id = menu.Id, 
       Title = menu.Title 
      } 
    }) 
    .ToDictionary(
     keySelector: item => item.viewModel.Id); 

var viewModels = tempModels 
    .Select(kv => 
     { 
      var viewModel = kv.Value.viewModel; 
      viewModel.Childs = kv 
       .Value 
       .childrenIds 
       .Select(childId => 
        tempModels[childId].viewModel) 
       .ToList(); 
      return viewModel; 
     }) 
    .ToList(); 
1

當您使用EF,你可以像下面的樣子:

public class BlogComment 
{ 
    public int Id { set; get; } 

    [MaxLength] 
    public string Body { set; get; } 

    public virtual BlogComment Reply { set; get; } 
    public int? ReplyId { get; set; } 
    public ICollection<BlogComment> Children { get; set; } 
}  



using (var ctx = new MyContext()) 
      { 
       var list = ctx.BlogComments 
          //.where ... 
          .ToList() // fills the childs list too 
          .Where(x => x.Reply == null) // for TreeViewHelper       
          .ToList(); 
      } 

用這種方式,你不需要使用遞歸查詢,但由於據我所知,當使用視圖模型獲取數據時,EF的動態代理被破壞。

約例如以上: 只需選擇的意見一個列表,並與

.Where(x=>x.Reply==null).Tolist() 

EF填寫評論的孩子財產。

Reference

0

深度問題,你可以使用像深度一個int屬性在模型中,那麼你可以這樣獲取數據:

public class BlogComment 
{ 
    public int Id { set; get; } 

    [MaxLength] 
    public string Body { set; get; } 
    public int Depth{get;set} 
    public virtual BlogComment Reply { set; get; } 
    public int? ReplyId { get; set; } 
    public ICollection<BlogComment> Children { get; set; } 
}  



using (var ctx = new MyContext()) 
      { 
       var list = ctx.BlogComments 
          .Where(a=>a.Depth<2) 
          .ToList() // fills the childs list too 
          .Where(x => x.Reply == null) // for TreeViewHelper       
          .ToList(); 
      } 

對該塞納里奧使用視圖模型,我與AutoMapper測試,但是當使用viewModel選擇數據時,EF生成的動態代理被銷燬。

請注意this Issue

相關問題