c#開發Mongo筆記第八篇


    到今天為止,Mongo開發的權限管理系統功能就做完了,剩下的就是完善構架,優化結構,只是現在c#操作Mongo的各種操作基本都掌握了

說到權限管理系統,其實再簡單不過了,在關系型數據的是時代,我們通常建一個菜單表,菜單用內建來管理子菜單,然后再建一個角色表(或用戶表),然后再建一個角色和菜單的對應關系表,存上菜單id和角色id的對應關系。當然了,方法很多,我只是

舉了一個相對比較常見的設計方式。

   用上Mongo之后我本來照搬以前的設計思路,完成了權限管理,完成之后突然覺得這樣不太好吧。比較Mongo是松散的文檔結構,和面向對象的思想有異曲同工之妙,這么設計看着也太不盡人意了。於是乎,我決定嘗試按照mongo的格式去重新設計。

首先第一步改造的是菜單,菜單不再使用內建,而是把子菜單當成一個字段存進父菜單那條數據里。然后修改的是角色,去掉了角色和菜單的對應表,把菜單直接存在了角色表里。

  這么改造完成之后開始是有一些不適應,當時查詢的時候確實方便了很多。

public   class Menu
    {
        public ObjectId _id { get; set; }


        public string Name { get; set; }

 
        public string  Url { get; set; }

        public string Icon { get; set; }

        public int OrderNo { get; set; }

        public string Descr { get; set; }
        public List<Menu> Child = new List<Menu>();
    }
    public class Role
    {

        public ObjectId _id { get; set; }

        public string Name { get; set; }

        public string RootMenu { get; set; }
        public string ChildMenu { get; set; }

        public List<Menu> Menus = new List<Menu>();
    }

   這樣改造之后,添加方法和查詢方法沒什么太大的變化,一開始不知道怎么添加和刪除子項。

后來發現官方的驅動還是很強大的,我們可以直接修改Menu或者Role對象,然后保存這個對象的修改結構就可以了,感覺和ef很相似了。

  還有現在點擊菜單傳回來一個id我無法知道它是一級菜單還是二級菜單了,因為二級菜單不是一條數據,所以也不能直接查詢了。我目前采用的辦法是先查詢一下是不是一級菜單,如果不是的話再查詢二級菜單。

這個辦法都是挺好用,當然了,大家肯定還有更好的辦法,希望大家不吝賜教啊。

貼一段修改菜單的方法,就當是拋磚引玉了

 ObjectId menuid = ObjectId.Parse(Request.Form["menuid"]);


                var query = Query.And(Query.EQ("Child._id", menuid));

                Menu menu = DAL.DALMenu.GetMenu(query);
                if (menu == null)
                {
                    query = Query.And(Query.EQ("_id", menuid));
                    menu = DAL.DALMenu.GetMenu(query);
                }

                if (menu.Child.Count(m => m._id == menuid) > 0)
                {
                    Menu child = menu.Child.FirstOrDefault(m => m._id == menuid);
                    child.Name = Request.Form["name"];
                    child.Icon = Request.Form["icon"];
                    child.Url = Request.Form["url"];
                    child.OrderNo = Convert.ToInt32(Request.Form["orderno"]);
                    child.Descr = Request.Form["descr"];
                 
              


                    DALMenu.Update(menu);

              
                }
                else
                {
                    menu.Name = Request.Form["name"];
                    menu.Icon = Request.Form["icon"];
                    menu.Url = Request.Form["url"];
                    menu.OrderNo = Convert.ToInt32(Request.Form["orderno"]);
                    menu.Descr = Request.Form["descr"];
             
                    DAL.DALMenu.Update(menu);
                }

最后效果如如下

 

數據庫的最終存儲結構如下圖,數據庫中文顯示亂碼問題我也解決了,只要改一下命令窗口的編碼就行了,默認的是gbk,改成utf-8的

雖然這樣role表顯的有些臃腫,但是用戶每次登陸肯定是要顯示菜單的,這些數據都是必須查詢出來的,所以臃腫也無所謂了。

如果需要查找role下面的一個子菜單的話,我是先讀出來它的一級菜單集合,然后再使用Linq的方式去查詢它的二級和三級菜單。

  Role role=DALRole.GetById(roleid);
            List<Menu> rolemenus = role.Menus;//該角色下一級菜單 集合
            foreach (var rolemenu in rolemenus)//循環一級菜單
            {
                cstr += "<div id=\"m" + rolemenu._id + "\" style=\"width: 150px;\">";

                List<Menu> childmenus = rolemenu.Child;
                if (childmenus.Count > 0)//有二級菜單
                {
                    str += "<a href=\"#\" class=\"easyui-menubutton\" data-options=\"menu:'#m" + rolemenu._id + "',iconCls:'" + rolemenu.Icon + "'\">" + rolemenu.Name + "</a>";
                    foreach (var m in childmenus)
                    {
                        cstr += GetChildMenus(m.Child, roleid, m._id, m.Name, m.Url);
                    }
                }
                else
                {
                    str += "<a href=\"#\"onclick=\"addTab('" + rolemenu.Name+ "','" + rolemenu.Url+ "')\" class=\"easyui-linkbutton\" data-options=\"plain:true,iconCls:'" + rolemenu.Icon + "'\">" + rolemenu.Name+ "</a>";
                }
                cstr += "</div>";
            }

貼出來起到一個拋磚引玉的作用吧。

其實Mongo的官方驅動本身已經很強大了,比較符合大家的c#開發習慣了,所以操作起來還是比較簡單的。順便提一下,查出來的時間會比實際時間小,需要屬性上加上標示

  /// <summary>
      /// 默認時間比真實時間小8個小時
      /// </summary>
      [BsonDateTimeOptions(Kind = DateTimeKind.Local)] 
        public DateTime CreateTime { get; set; }

我把我遇到的問題基本上都總結出來了,我覺得可能大家在初次接觸的時候也會遇到相同的問題,所以整理出來共享一下,也作為自己的一個學習筆記。

下一步就是整理框架了,如果整理之后有什么心得的話我也會拿出來分享的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM