【问题标题】:Populating a TreeView from a database model in Razor Pages从 Razor 页面中的数据库模型填充 TreeView
【发布时间】:2019-09-16 05:08:16
【问题描述】:

我有一个 Razor 页面项目,它试图从使用数据模型创建的数据库中填充 Kendo TreeView(或任何其他 TreeView)。

这些是模型的相关字段:

namespace FliveRetry.Models
{
    public class Org
    {
        public int ID { get; set; }
        public string OrgName { get; set; }
        public int? ParentID { get; set; }
        public bool? HasChildren { get; set; }
    }
}

这是视图调用:

@(Html.Kendo().DropDownTree()
    .Name("selectedOrgs")
    .DataTextField("Org")
    .DataValueField("OrgID")
    .Checkboxes(true)
    .DataSource(d => d
        .Read(read =>
            read.Url("/Apps/Edit?handler=Read")
        )
    )
)

在 OnGetRead 中将值硬编码到如下列表中可以正常工作:

public IActionResult OnGetRead(int? id)
    {       
        var data = new List<Org>()
        {
            new Org() { ID = 1, ParentID = null, HasChildren = true, OrgName = "Org1" },
            new Org() { ID = 2, ParentID = null, HasChildren = false, OrgName = "Org2" },
            new Org() { ID = 3, ParentID = 1, HasChildren = true, OrgName = "Org3" },
            new Org() { ID = 4, ParentID = 3, HasChildren = false, OrgName = "Org4" }
        };

        var result = data.Where(x => id.HasValue ? x.ParentID == id : x.ParentID == null)
            .Select(item => new {
                id = item.ID,
                Org = item.OrgName,
                hasChildren = item.HasChildren
            });
            return new JsonResult(result);
        }
    }

Hard Coded Values Image

我正在尝试遍历 Org 集合以使用数据库中的 Orgs 填充树视图。

将 for 循环放在 List 声明中会到处产生错误,OnGetRead 本身表示并非所有代码路径都返回值:

public IActionResult OnGetRead(int? id)
        {
            var blnChildren = false;
            var data = new List<Org>()
            {       
                foreach (var item in _context.Org)
                {
                    blnChildren = false;
                    if (item.ParentID.Equals(null))
                        {
                        blnChildren = true;
                        }
                    new Org() { ID = item.ID, ParentID = item.ParentID, HasChildren = blnChildren, OrgName = item.OrgName };
                }       
            };

            var result = data.Where(x => id.HasValue ? x.ParentID == id : x.ParentID == null)
                .Select(item => new {
                    id = item.ID,

                    Org = item.OrgName,
                    hasChildren = item.HasChildren
                });

            return new JsonResult(result);
        }

如果我将 for 循环放在列表声明之外,循环会正确填充但结果为空,我猜是因为项目声明在列表之外?

public IActionResult OnGetRead(int? id)
        {
            var blnChildren = false;
            var data = new List<Org>()
            {       

            };
            foreach (var item in _context.Org)
            {
                blnChildren = false;
                if (item.ParentID.Equals(null))
                    {
                    blnChildren = true;
                    }
                new Org() { ID = item.ID, ParentID = item.ParentID, HasChildren = blnChildren, OrgName = item.OrgName };
            }

            var result = data.Where(x => id.HasValue ? x.ParentID == id : x.ParentID == null)
                .Select(item => new {
                    id = item.ID,
                    Org = item.OrgName,
                    hasChildren = item.HasChildren
                });

            return new JsonResult(result);
        }

不确定我的问题是与 C# 相关还是与模型相关,但我们将不胜感激。

如果我走错了路,任何其他从剃刀项目中的数据库模型而不是 MVC 项目中工作的自引用树视图的工作示例也会有所帮助。

我有另一个使用 Kendo.Mvc.UI.TreeViewItemModel 数据的相同问题示例,我也无法在硬编码之外工作,我只需要任何真正有效的版本。

谢谢大家

【问题讨论】:

    标签: c# razor treeview razor-pages kendo-treeview


    【解决方案1】:

    你需要纠正很多东西。

    1. 在 forach 循环中,您将遍历 DB 中的每个 Org 表项,每次都创建对数据库的查询。那是浪费时间和资源。您应该首先从数据库中查询您需要的所有项目,然后处理它们。如果您需要所有表格条目,您可以将它们具体化。
        var orgs = _context.Org.ToArray();
        foreach(var item in orgs)
        {
           //code here
    
    1. 您没有将项目添加到 foreach 循环内的数据列表中。你可以这样做
        var tmpOrg = new Org() { code code code} ;
        data.Add(tmpOrg);
    
    1. 整个事情可以简化为一个表达式。您不需要具体化整个表格,也不需要那个 foreach 循环。您可以更改结果表达式以使用 _context.Org 而不是数据。在 hasChildren 的 Select 子句中,您可以更改此行
        hasChildren = item.ParentID == null ? true : false;
    

    编辑

    你应该留下的是

    public IActionResult OnGetRead(int? id)
    {       
        var result = _context.Org.Where(x => id.HasValue ? x.ParentID == id : x.ParentID == null)
                                 .Select(item => new 
                                  {
                                      OrgID = item.ID,
                                      Org = item.OrgName,
                                      HasChildren = item.ParentID == null ? true : false
                                  });
    
        return new JsonResult(result);       
    }
    
    

    【讨论】:

    • 谢谢@Arthur,这听起来很棒。不幸的是,我的技能还不是很好,我不知道如何组合起来。下面是我整理的,但它不正确:` var orgs = _context.Org.ToArray(); var data = new List() { }; var tmpOrg = new Org() { data.Add(tmpOrg); }; var result = data.Where(x => id.HasValue ? x.ParentID == id : x.ParentID == null) .Select(item => new { id = item.ID, Org = item.OrgName, hasChildren = item.ParentID == null ? true : false });返回新的 JsonResult(结果); `
    • 显然还没有弄清楚如何正确回复 cmets :(
    • @tonyRyan 你快到了。删除实现 Org 表的第一行。删除第二行(顺便说一句,如果您不使用值初始化列表,则可以省略花括号)。您不需要 tmpOrg 的第三行。在第四行用 '_context.Org' 替换 'data' 并删除 Where(...) 子句。就是这样:)
    • 谢谢@Arthur。不幸的是,我迷路了。感谢您的帮助,我很高兴向您推荐、打勾、分享或付钱给您以帮助我给出实际答案。我只需要一个工作示例来复制。这就是我现在的情况,你能解决它吗? Telerik 除了硬编码的解决方案之外似乎什么都给不了我。谢了哥们。 ` public IActionResult OnGetRead(int?id) { }; var result = _context.Org.Select(item => new { id = item.ID, Org = item.OrgName, hasChildren = item.ParentID == null ? true : false });返回新的 JsonResult(结果); } `
    • @TonyRyan 我已经编辑了答案并添加了解决方案。我还更改了 Select 子句中的属性名称,因为我可以看到在 Kendo 中您将 dataTextFiled 绑定到我假设是组织名称的 Org 文件。我还将 id 更改为 OrgID,因为您也在 Kendo 中绑定到它。请不要忘记接受答案:)。
    猜你喜欢
    • 2010-09-26
    • 1970-01-01
    • 2017-05-02
    • 2011-03-24
    • 2020-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多