到今天为止,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) > )
{
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 > )//有二级菜单
{
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; }

我把我遇到的问题基本上都总结出来了,我觉得可能大家在初次接触的时候也会遇到相同的问题,所以整理出来共享一下,也作为自己的一个学习笔记。

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

c#开发Mongo笔记第八篇的更多相关文章

  1. c#开发Mongo笔记第六篇

    之前写的五篇比较得到了大家的积极反馈,也有个别高手对我写我写出的代码进行了指教. 其中提到的我写的查询方法性能有问题,我想了想,如果mongo不是延时加载的话,那我的查询就真的有问题了,就成了查询出来 ...

  2. c#开发Mongo笔记第四篇

    今天是个伟大的日子,不得不说小苹果的歌词真是深入人心啊. 不过今天伟大并不是因为我种下一颗种子,而是我从今天不再写demo,而是进入项目的正式开发当中,毕竟项目时间有限(想必各位码农也都深有体会吧), ...

  3. c#开发Mongo笔记第七篇

    开发到这里遇到了一些问题,哪到这里想请教一下大家 今天我完成的是菜单功能, public class Menu { public ObjectId _id { get; set; } public i ...

  4. c#开发Mongo笔记第三篇

    今天主要测试了一下查询功能了,当然了主要还是为了让查询可以和我们平时使用的实体对象关联起来,并且 那些BsonDocument和Collection我们操作起来不是太方便的 还是首先定义了一个用户类, ...

  5. c#开发Mongo笔记第五篇

    现在增删查改算是都完成了,但是查询算是有点不完美的,相信现在用juqeryeasyui这一类的插件的人应该也不少吧,这样的话前台展示需要JSON格式的数据, 好在mogno驱动提供toJson()的函 ...

  6. ASP.NET Core Web开发学习笔记-1介绍篇

    ASP.NET Core Web开发学习笔记-1介绍篇 给大家说声报歉,从2012年个人情感破裂的那一天,本人的51CTO,CnBlogs,Csdn,QQ,Weboo就再也没有更新过.踏实的生活(曾辞 ...

  7. c#开发Mongo笔记第二篇

    写到第二篇不得不说是我之前犯了一个小错误,其实实现子表存储也是很简单的事,先说我想实现什么样的效果吧 就是用户表里有个成绩字段,成绩字段是个子表 其实实现这个功能也很简单,用面向对象的思想很好理解,子 ...

  8. c#开发Mongo笔记第一篇

    现在开发的这个项目要用mongo数据库开发,发现网上的这方面教程还是比较少的,只能边看官方说明边进行开发,再开发过程中写下笔记,也算上是一个总结吧. 我开发使用的是vs2013了,驱动用的是最新的1. ...

  9. c#开发Mongo笔记第九篇

    用skip略过少量的文档还是不错的.但是要是数量非常多的话,skip就会变得很慢,因为要先找到需要被略过的数据,然后再抛弃这些数据.大多数数据库都会在索引中保存更多的元数据,用于处理skip, 但是m ...

随机推荐

  1. 使用lipo 查看静态库命令

    lipo -info .a 的: find . -name *.a -exec lipo -info "{}" \; framework 的: find . -name *.fra ...

  2. Tomcat长出现的内存溢出问题

    以下内容转载自博客:http://www.cnblogs.com/apaqi/archive/2012/07/09/2582480.html 在eclipse.ini配置文件中加上以下两行 -XX:P ...

  3. java io流 运行错误时,保存异常到文件里面

    java io流 运行错误时,保存异常到文件里面 下面这个实例,运行后,输入数字,为正确,如果输入字符串,则报错,保存错误信息 //运行错误时,保存异常到文件里面 //下面这个实例,运行后,输入数字, ...

  4. Android Gradle 技巧之二: 最爱命令行

    命令行 很多做 Android 开发不久的同学,习惯于使用图形界面,对命令行操作很陌生甚至恐惧.遇到 AS 运行错误,束手无策.AS 为了确保易用性,也在 UI 界面上屏蔽了很多命令行运行的细节,导致 ...

  5. java byte转无符号int

    import java.io.ByteArrayInputStream; public class Test{ public static void main(String[] args) { byt ...

  6. elasticsearch auto delete old indices

    定在crontab 每天执行 crontab -e * 2 * * * ~/autodelete.py Python 代码如下 #!/usr/bin/env python # encoding:utf ...

  7. 就是这么简单!使用Rest-assured 测试Restful Web Services

    使用 Rest-assured 测试 Restful Web Services 转载注明出处: http://www.cnblogs.com/wade-xu/p/4298819.html 这里向大家介 ...

  8. jQuery MiniUI 开发指南+API组件参考手册

    jQuery MiniUI 开发指南 本文档将逐步的讲解jQuery MiniUI的方方面面,从此您将踏上jQuery MiniUI的深入探索之旅.                 1.Hello M ...

  9. X-Cart 学习笔记(一)了解和安装X-Cart

    目录 X-Cart 学习笔记(一)了解和安装X-Cart X-Cart 学习笔记(二)X-Cart框架1 X-Cart 学习笔记(三)X-Cart框架2 X-Cart 学习笔记(四)常见操作 一.了解 ...

  10. goldengate 参数之GETTRUNCATES | IGNORETRUNCATES --转载

    GETTRUNCATES | IGNORETRUNCATESValid ForExtract and ReplicatDescriptionUse the GETTRUNCATESand IGNORE ...