使用笛卡尔积解决一个实际的问题

  最近项目中遇到这样一个问题,场景是:

  我需要给所有的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)

 

 

posted @ 2012-06-17 12:06  _小阳  阅读(1883)  评论(0)    收藏  举报