最近正在学习MVC,也入手开始从框架到需求方面的编写。
框架方面,@洞庭夕照那边已经有了一个不错的开头,当然我们都是借鉴别人的项目代码。
最近打算在做一个【组织结构】+【权限】的系统。系统的功能是这样的。可以同时为多家公司提供人员管理及权限配置。要求达到通用!
最终我设计出来的是这样的东西!
具体解释:
1、SysAdmin: 系统总管理员,对整个系统有权限免疫特性。
它对系统有全局设置功能
2、WorkGroup:类似一个公司或者一个组织。
它是整个系统中,用户的最顶级。公司下可以有不同的职务UserRole(权限也不同)
3、UserRole:这个表相当于公司下不同的部门或者职务(财务,开发,公关等)
公司一般不直接跟职员关联,因为职员隶属于公司的某个部门。
4、UserRoles:一个员工可以在多个公司的多个部门下任职(兼职什么的,身兼数职的人大有人在)
本来没想过这个表,后来发现,一个人确实可以在多个公司或者组织,任不同职务,有不同的角色权限。所以才加上这个表。这样一个用户的账号密码,可以登录到不同的公司,行使自己的权利。
5、UserBase:员工的登录表。
为啥它叫base 因为,在这个系统中,用户什么都可以没有,但是,起码要有账号和密码。
以上5个表中,2、3、4、5阐述了一个组织的结构。
6、SysMenu:系统全局的系统菜单。系统所有的功能连接都在这里。
7、UserMenu:用户的菜单,根据用户的权限不同,用户看到的菜单也是不同的。
8、SysOperation:系统操作权限的集合表。因为是MVC开发的,所以,任何一个操作都对应的是一个action,action上面是控制器和区域,所以,把他们都录入到数据库,作为权限使用。
9、UserOperation:用户的操作权限,用于的权限不同,能使用的功能自然不同。
以上 6、7、8、9 这4个表阐述了系统权限和用户权限。有人问,为什么菜单和权限不做成1V1的形式,这样更方便呢?
首先说操作权限,操作权限基本分3种情况:
系统级的(只有管理员才能用)
限制级别(针对系统注册账号)
开放级别(所有人都可以无论登录与否)
所以我们重点做限制级别的……
其次在说菜单:
菜单也可以说是链接!举例,淘宝网站,不登录和登录的区别是能否买东西。所以,菜单也好,链接也好,对应的权限未必一定是一种情况!
也就是说,登录不登录都能看到,但只有登录才能用!
所以,我在这个地方设计成自由的,灵活的,非耦合的。虽然操作上多了一步,但可调整性能却高了一步!
\\===================================================================
大致的流程如下:
一、系统管理员
1、设置权限等级
2、设置菜单等级
3、审批申请管理员的操作
4、系统日志
5、数据观察与维护
二、管理员(用户公司或者组织权限的,不是系统管理员,你可以叫他是老板。)
1、注册账号
2、申请一个workgroup(相当于注册公司)
3、系统管理员批准通过
4、进入workgroup管理界面进行操作
操作的内容基本是:a----增加角色userRole(相当职务--公司不可能都是老板,肯定要有财务等一系列职务)
b----针对角色userRole做给他们相应的权限userOperation以及可以看到的菜单userMenu
c-----审批申请加入本组织的用户
d-----其他(这个系统不可能不做别的,单独有组织框架和权限框架,不干活,那也不行,所以系统会有更具体的工作,比如办公OA什么的)
二、普通用户
1、注册账号
2、申请加入某组织或者公司
3、等待组织或者公司的审批
4、进入系统 --- 开始工作(工作的内容基本就是体统提供的其他功能)
//===============================================================
本文的主题还有另外一个就是外键。
外键的作用无非就是约束,保证数据有效。
对于用外键的性能和不用外键的性能,个人觉得在我的开发领域可以忽略不计 —— 菜鸟生涯就这样吧,大牛见了别喷就好!
本人在使用code first发现,使用外键有点不方便,而且联合查询也没节省多少代码量,因为本人之前没用过linq基本都是使用SQL,而且以前也没用外键的习惯(水平有限也好,习惯也好,这都无所谓)总之,我开始不想用外键了!
经过反复的测试,总结了一下:
不用外键一样可以用EF 做code first 开发 —— 放弃了延迟加载和外键约束而已!
特此贴出测试代码。
1 //INNER JOIN 2 var query = (from u in db.UserBase 3 from g in db.UserGroup 4 where u.ID == g.PID 5 select u).ToList(); 6 //INNER JOIN 7 var query = (from a in db.UserBase 8 join b in db.UserGroup on a.ID equals b.PID 9 select new Test { id = a.ID, pid = b.PID, name = a.LoginName, Group = b.GroupName } 10 ).ToList(); 11 12 //INNER JOIN 13 var query = (from a in db.UserBase 14 join b in db.UserGroup on a.ID equals b.PID 15 join c in db.WorkGroup on b.GroupName equals c.GroupName 16 select new Test { id = a.ID, pid = b.PID, name = a.LoginName, Group = b.GroupName } 17 ).ToList(); 18 //CROSS JOIN 19 var query = (from u in db.UserBase 20 from g in db.UserGroup 21 select u).ToList(); 22 23 //LEFT OUTER JOIN 24 var query = (from a in db.UserBase 25 join b in db.UserGroup on a.ID equals b.PID into order 26 from o in order.DefaultIfEmpty() 27 //where o != null 28 select new Test 29 { 30 id = a.ID, 31 Group = o == null ? "null" : o.GroupName, 32 name = a.LoginName, 33 pid = o == null ? 0 : o.PID 34 } 35 ).ToList();