Asp.Net MVC + WCF (1) 数据树控件显示

做一个后台管理网站,用Asp.Net MVC做,最后用WCF给CS客户端。

Controller和View都用VS自动生成的,试着在DbContext外加了个BLL层,当前还看不到必要性,先放着。

基本的类结构弄好后,开始正式做界面。
第一个问题,树机构的增删改查。
参考: MVC+EF处理树形结构

有树结构的类是
    /// <summary>
    /// 机构
    /// </summary>
    public class Department
    {
        public int Id { get; set; }

        [Display(Name="机构名")]
        public string Name { get; set; }

        [Display(Name = "排序")]
        public int ShowOrder { get; set; }

        [Display(Name = "上级机构")]
        public virtual Department Parent { get; set; }
    }
初始化代码
Department dep1 = new Department() { Id = 0, Name = "机构", ShowOrder = 0, Parent = null };
Department dep2 = new Department() { Id = 1, Name = "机构1", ShowOrder = 0, Parent = dep1 };
Department dep3 = new Department() { Id = 2, Name = "机构2", ShowOrder = 1, Parent = dep1 };
Department dep4 = new Department() { Id = 3, Name = "机构3", ShowOrder = 2, Parent = dep1 };
Department dep5 = new Department() { Id = 4, Name = "机构4", ShowOrder = 0, Parent = dep2 };
Department.AddRange(new List<Department>() { dep1, dep2, dep3, dep4, dep5 });

表结构
无论是给前端还是给CS,Parent_Id属性都要在对象中明确声明,因为如果用Parent属性传递,Parent属性的序列化过程可能是递归的。

改为

    /// <summary>
    /// 机构
    /// </summary>
    public class Department
    {
        public int Id { get; set; }

        [Display(Name="机构名")]
        public string Name { get; set; }

        [Display(Name = "排序")]
        public int ShowOrder { get; set; }

        [Display(Name = "上级机构")]
        public virtual Department Parent { get; set; }

        public int? ParentId { get; set; }
    }

注意:int? 如果改成 int 初始化数据或者添加数据时会出问题

“System.Data.Entity.Infrastructure.DbUpdateException”类型的异常在 EntityFramework.dll 中发生,但未在用户代码中进行处理

其他信息: 无法确定依赖操作的有效顺序。由于外键约束、模型要求或存储生成的值,因此可能存在依赖关系。

这个提示我是看不出和int?有什么关系的
按我理解没有?就变成了不能为空,我的初始化数据中有个为空的,所以就出错了。
另外有个外键约束在ParentId上,不能为空,根节点的父不存在的,也就出错了。

继续树显示问题
为了递归获取子节点,添加Children属性

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

        [Display(Name="机构名")]
        public string Name { get; set; }

        [Display(Name = "排序")]
        public int ShowOrder { get; set; }

        [Display(Name = "上级机构")]
        public virtual Department Parent { get; set; }

        public int? ParentId { get; set; }

        [ForeignKey("ParentId")]
        public virtual ICollection<Department> Children { get; set; }
    }

添加HtmlHelper扩展方法

namespace System.Web.Mvc
{
    public static class MyHtmlHelper
    {
        public static MvcHtmlString Tree(this HtmlHelper html, Department treeModel)
        {
            return BindTree(treeModel);
        }

        private static MvcHtmlString BindTree(Department treeModel)
        {
            StringBuilder sb = new StringBuilder();
            if (treeModel != null)
            {
                sb.Append("<ul>");

                List<Department> list = treeModel.Children.ToList();
                foreach (var item in list)
                {
                    sb.Append("<li>");
                    sb.Append(item.Name);
                    sb.Append("</li>");
                    sb.Append(BindTree(item));
                }
                sb.Append("</ul>");

            }
            MvcHtmlString mstr = new MvcHtmlString(sb.ToString());
            return mstr;
        }
    }
}

这个方法不够通用,改造一下,写个接口

    public interface ITreeNode<T>
    {
        string Name { get; set; }
        ICollection<T> Children { get; set; }
    }
继承接口:
public class Department: ITreeNode<Department>

面向接口编程:
namespace System.Web.Mvc
{
    public static class MyHtmlHelper
    {
        public static MvcHtmlString Tree<T>(this HtmlHelper html, ITreeNode<T> treeModel) where T : ITreeNode<T>
        {
            return BindTree(treeModel);
        }

        private static MvcHtmlString BindTree<T>(ITreeNode<T> treeModel) where T : ITreeNode<T>
        {
            StringBuilder sb = new StringBuilder();
            if (treeModel != null)
            {
                sb.Append("<ul>");

                List<T> list = treeModel.Children.ToList();
                foreach (T item in list)
                {
                    sb.Append("<li>");
                    sb.Append(item.Name);
                    sb.Append("</li>");
                    sb.Append(BindTree(item));
                }
                sb.Append("</ul>");

            }
            MvcHtmlString mstr = new MvcHtmlString(sb.ToString());
            return mstr;
        }
    }
}

使用上和原来的函数一样。
Controller中添加一个Action
        public ActionResult Tree()
        {
            return View(db.Departments.GetRoot());
        }

GetRoot()是获取根节点,多个根节点的情况后面在改造。
添加一个View,使用Tree扩展函数
@model Location.Model.Department

@{
    ViewBag.Title = "Tree";
}

<h2>Tree</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<div>
    @Html.Tree(Model)
</div>

结果:

下一个问题,创建子节点

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值