使用笛卡尔积解决一个实际的问题
最近项目中遇到这样一个问题,场景是:
我需要给所有的Employee分配几个权限(Role),由于项目中用的Nhibernate,用的是QBC查询这样完成这个操作的伪代码大概是:
for(Employee emp in employees) { for(Role role in Roles) { emp.Roles.Add(role);//Employees和Roles双向关联,Roles端inverse = true } }
这样就有个问题,2次循环复杂度相当高,而且每执行一次emp.Roles.Add(role) 都会生成一句Sql,这么多的Sql真的是让人无法接受的?
也许你跟我一样开始抱怨ORM框架不是那莫Perfect,最近开了Martin Flower的文章OrmHate让我也更平和的心态去认识Orm框架,它并不是万能的,也需要我们有底层的数据库知识,对表的结构很清楚。
回到上面的问题,我们可以直接向Employee和Role的中间表插入数据,这样就能一句Sql解决问题,但是怎么写这句Sql呢?这里笛卡尔积就能帮助我们。
我还是来个完整的例子:
use tempdb if object_id('employee') is not null drop table employee go create table employee ( empid int identity(1,1) primary key, empname varchar(20) not null ) go create table [role] ( roleid int identity(1,1) primary key, description varchar(50) not null ) go create table emp_role ( id int identity(1,1) primary key, empid int foreign key references employee(empid), roleid int foreign key references [role](roleid) ) go insert into employee values('Jacky') insert into employee values('Wendy') insert into employee values('David') insert into employee values('Lucy') insert into employee values('Tom') insert into employee values('Ann') insert into [role] values('Create Training') insert into [role] values('Training') insert into [role] values('Manage Employee') insert into [role] values('Manage Deparement')
这样我们跟所有Employee添加权限就只需要插入中间表就行了!我们可以这样写:
--向所有员工添加权限(Id为1,2) insert into emp_role select empid,roleid from employee e cross join [role] r where r.roleid in (1,2)
浙公网安备 33010602011771号