您的位置:首页 > 其它

一个双实体多对多关系的操作

2007-07-14 16:00 183 查看
在蓝色理想看到了这样一个帖子:

http://bbs.blueidea.com/thread-2768623-1-1.html

他提出了一个问题,就是一个双实体以及其多对多关系的显示问题,原题如下:

一共三个表..
表一(student)
id name
1 A
2 B
3 C

表二(teacher)
id teachername
1 张三
2 李四
3 王五

表三(studenttoteacher)
id studentid teacherid
1 1 1
2 1 2
3 1 3
4 2 1
5 2 3
6 3 2
7 3 3

表三第一二三条记录表示的意思是学生ID为1的学生有三个老师 ID分别是1 2 3,依此类推

输入结果要求如下图..学生老师要求可以再添加



问题抽象其实是这样的

有三个表,分别是实体A、实体B以及两个实体之间的多对多关系,现在的需求是,显示一个html表格,要求在这个表格里面显示两实体之间各记录是否有对应的关系。并且这里面的实体,是可以动态的添加的。

而我的思路是这样的,首先取出两实体A、B的名称,同时获得其条目数,而后定义一个二维数组,用于以矩阵的形式存放二者的关系,而后再进行显示。

我给出的代码如下:


<%


Option Explicit


Dim sConn,oConn,sSql,oRs,i,j


Dim aSet,lRowCount,lColCount,aStudents,aTeachers


Dim lLastID


sConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("source.mdb")


Set oConn = Server.CreateObject("ADODB.Connection")


Set oRs = Server.CreateObject("ADODB.RecordSet")


oConn.Open sConn


'学生部分记录


sSql = "SELECT * FROM [student]"


oRs.Open sSql,oConn,1,1


lLastID = 0


While Not oRs.Eof


For i = 1 To (oRs("id")-lLastID)


aStudents = aStudents & ","


Next


aStudents = aStudents & oRs("name")


lLastID = oRs("id")


oRs.MoveNext


Wend


oRs.MoveLast


lColCount = oRs("id")


oRs.Close


'教师部分记录


sSql = "SELECT * FROM [teacher]"


oRs.Open sSql,oConn,1,1


lLastID = 0


While Not oRs.Eof


For i = 1 To (oRs("id")-lLastID)


aTeachers = aTeachers & ","


Next


aTeachers = aTeachers & oRs("name")


lLastID = oRs("id")


oRs.MoveNext


Wend


oRs.MoveLast


lRowCount = oRs("id")


oRs.Close


'字符恢复为数组


aStudents = Split(aStudents,",")


aTeachers = Split(aTeachers,",")


'获得关系集合数组


ReDim aSet(lColCount,lRowCount)


sSql = "SELECT * FROM [studenttoteacher]"


oRs.Open sSql,oConn


While Not oRs.Eof


aSet(oRs("studentid"),oRs("teacherid")) = "ok"


oRs.MoveNext


Wend


oRs.Close


Set oRs = Nothing


%>


<table border="1">


<!--首行输出教师名称-->


<tr>


<th width="50"> </th>


<%For i = 1 To UBound(aTeachers)%>


<%If aTeachers(i) <> "" Then%>


<th width="50"><%=aTeachers(i)%></th>


<%End If%>


<%Next%>


</tr>


<!--依次输出每个学生的行-->


<%For i = 1 To UBound(aStudents)%>


<tr>


<th width="50"><%=aStudents(i)%></th>


<%For j = 1 To UBound(aTeachers)%>


<%If aTeachers(j) <> "" Then%>


<td align="center">


<%


If aSet(i,j)="ok" Then


Response.Write "√"


Else


Response.Write " "


End If


%>


</td>


<%End If%>


<%Next%>


</tr>


<%Next%>


<%


oRs.Close


Set oRs = Nothing


oConn.Close


Set oConn = Nothing%>


</table>

这里面有两个难点:

第一,效率问题。如果不考虑效率问题,那么我们蛮可以使用循环嵌套,外部循环所有的实体A,内部循环实体B,在内部循环中打开记录集查询关系表中是否有A和B当前条目的对应关系,但是这样的效率太低了,我们需要的记录集查询次数就是A条目数*B条目数+2,如果A和B都很多的话,那么将是一个恐怖的查询。

那么我们解决的方法就是将关系表中的记录全部一次取出,并放在二维数组矩阵中,假如当前第N行第M列有关系,那么设定此成员的值为"ok"。而后在表格的显示中判断当前行列的元素的值是否为"ok"就可以判断当前位置的元素是否应当显示"√"以表示是否有关系了。

第二,动态添加问题。其实这里的添加不仅仅指添加,他主要解决的是数据库内元素的变动问题,设想,假如我删除了某一个实体中的某一条记录,那么此时不加以处理的话,数组就会乱套而无法判定当前行列的记录是否是数据库中指定id的记录,因此我采用了这样的代码:


For i = 1 To (oRs("id")-lLastID)


aTeachers = aTeachers & ","


Next


aTeachers = aTeachers & oRs("name")


lLastID = oRs("id")


oRs.MoveNext



来保持数组中的次序和id保持完全的一致。因为考虑到数据库中数据可能有删除导致id不连续的情况
aSet数组中的下标对应的是id
而aStudents和aTeachers数组的下标对应的是记录在数据库中是第几个,如果中间你删除了student或者teacher的记录,那么这个序号就不对应了,因此我用那个方法,使得aStudents和aTeachers保证对应的是id。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐