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

相关问题