WSORM:为WSBLog写的简单ORM(六)
也许有人说,搞个Blog而已,需要费那么大劲搞个什么WSORM出来么?那么,我们来看看,即使做一个简单的Blog,ORM到底有没有它的价值,到底ORM是把WSBLOg的实现搞复杂了还是搞简单了?
我设想的WSBLog是支持分级的树形目录的,关于树形目录的样子,可以参考一下我这个测试中的WSBLog网站:http://www.66ph.com。
题外话,这个测试BLOG有13万篇文章,由于目前程序中没有使用任何缓存优化机制,速度有点慢。我对WSBLog的目标呢,是做一个快速、稳定、多用户的BLOG,关于这些想法,可以看看我的BLOG上的相关文章:
http://www.wubuku.com/post/125.aspx
http://www.wubuku.com/post/34.aspx
言归正传,引入WSORM之后,目录类TCategory、数据库中的目录表blog_Category、以及它们之间的映射关系如下:
Public Class TCategory Class TCategory
Inherits EntityBase

Public Shared Function GetObjectMap()Function GetObjectMap() As ObjectMap
'blog目录表blog_Category的建表脚本
'CREATE TABLE [dbo].[blog_Category] (
' [cate_ID] [int] IDENTITY (1, 1) NOT NULL ,
' [cate_Name] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
' [cate_Order] [nvarchar] (10) COLLATE Chinese_PRC_CI_AS NULL ,
' [cate_Intro] [nvarchar] (255) COLLATE Chinese_PRC_CI_AS NULL ,
' [cate_Count] [int] NOT NULL ,
' [cate_Code] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
' [cate_ParentCode] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
' [cate_ParentID] [int] NULL
') ON [PRIMARY]
Dim omap As ObjectMap = New ObjectMap(GetType(TCategory), "blog_Category")
omap.MemberMaps.Add("ID", "cate_ID", DbFieldTypes.Int, MemberMapTypes.Identity)
omap.MemberMaps.Add("Name", "cate_Name", DbFieldTypes.String, MemberMapTypes.NormalField)
omap.MemberMaps.Add("Order", "cate_Order", DbFieldTypes.String, MemberMapTypes.NormalField)
omap.MemberMaps.Add("Intro", "cate_Intro", DbFieldTypes.String, MemberMapTypes.NormalField)
omap.MemberMaps.Add("Count", "cate_Count", DbFieldTypes.Int, MemberMapTypes.NormalField)
omap.MemberMaps.Add("Code", "cate_Code", DbFieldTypes.String, MemberMapTypes.NormalField)
omap.MemberMaps.Add("ParentCode", "cate_ParentCode", DbFieldTypes.String, MemberMapTypes.NormalField)
omap.MemberMaps.Add("ParentID", "cate_ParentID", DbFieldTypes.Int, MemberMapTypes.NormalField)
'目录之间的父子关系是通过这句关联起来的
omap.MemberMaps.Add("Childs", "cate_ID", DbFieldTypes.Int, GetType(TCategory), "cate_ParentID", MemberMapTypes.One2Many)
Return omap
End Function

Public ID As Integer'目录的ID
Public Code As String'目录的代码
Public Name As String
Public Intro As String
Public Order As String 'Public Order As Integer
Public Count As Integer
Public ParentID As Integer'父级目录的ID
Public ParentCode As String'父级目录的代码
Public Childs() As TCategory

Public ReadOnly Property Url()Property Url() As String
Get
Url = BLOG_HOST & "Catalog.aspx?" & "cate=" & ID
End Get
End Property
End Class 
题外话,为了便于人的识读和查询,上面的数据表在设计上留有一些冗余字段,虽然在绝大多数时候,我们不需要使用这些字段。我个人认为在数据库中适当使用冗余字段是个良好的设计习惯。
我们看看使用了WSORM后,代码怎么写:
Dim sessionFactory As com.oucsoft.WSORM.SessionFactory = New com.oucsoft.WSORM.SessionFactory
sessionFactory.FactoryType = WSORM.SessionFactoryTypes.SqlServer ' 设置生成的Session的类型
sessionFactory.ConnectionString = Me .ConnectionString ' 设置连接字符串
sessionFactory.ObjectMaps.Add(TCategory.GetObjectMap()) ' 添加映射关系
' 取得树形的目录信息 
Public Function GetTreeViewCategorys() Function GetTreeViewCategorys() As TCategory()
Dim session As com.oucsoft.WSORM.ISession = sessionFactory.CreateSession()
'只要查询顶级目录,就会级联取得所有子目录的信息
Return CType(session.Query(GetType(TCategory), "(ParentID IS NULL OR ParentID=0) ORDER BY Code"), TCategory())
End Function 


——除去映射信息的设置(SessionFactory是整个BLOG程序里公用的,只需要设置一次),取得所有目录树的代码其实只有两行,一切就是这么简单。可见,ORM的引入对于优化BLOG程序的代码结构还是很有好处的。
为了在html页面上生成树形目录,我们希望输出类似这样的html代码:

< li class ="Closed" >< a href ="http://localhost/WSBLog/Catalog.aspx?cate=1" > 农、林、牧、渔业 (14) a > < a href ="http://localhost/WSBLog/Rss.aspx?cate=1" target ="_blank" > < img src ="http://localhost/WSBLog/IMAGE/LOGO/rss.png" border ="0" alt ="rss" > a >
< ul >
< li class ="Closed" >< a href ="http://localhost/WSBLog/Catalog.aspx?cate=2" > 农业 (3) a > < a href ="http://localhost/WSBLog/Rss.aspx?cate=2" target ="_blank" > < img src ="http://localhost/WSBLog/IMAGE/LOGO/rss.png" border ="0" alt ="rss" > a >
< ul >
< li class ="Child" >< a href ="http://localhost/WSBLog/Catalog.aspx?cate=3" > 谷物及其他作物的种植 (0) a > < a href ="http://localhost/WSBLog/Rss.aspx?cate=3" target ="_blank" > < img src ="http://localhost/WSBLog/IMAGE/LOGO/rss.png" border ="0" alt ="rss" > a > li >< li class ="Child" >< a href ="http://localhost/WSBLog/Catalog.aspx?cate=13" > 蔬菜、园艺作物的种植 (0) a > < a href ="http://localhost/WSBLog/Rss.aspx?cate=13" target ="_blank" > < img src ="http://localhost/WSBLog/IMAGE/LOGO/rss.png" border ="0" alt ="rss" > a > li >< li class ="Child" >< a href ="http://localhost/WSBLog/Catalog.aspx?cate=17" > 水果、坚果、饮料和香料作物的种植 (0) a > < a href ="http://localhost/WSBLog/Rss.aspx?cate=17" target ="_blank" > < img src ="http://localhost/WSBLog/IMAGE/LOGO/rss.png" border ="0" alt ="rss" > a > li >< li class ="Child" >< a href ="http://localhost/WSBLog/Catalog.aspx?cate=1200" > 中药材的种植 (0) a > < a href ="http://localhost/WSBLog/Rss.aspx?cate=1200" target ="_blank" > < img src ="http://localhost/WSBLog/IMAGE/LOGO/rss.png" border ="0" alt ="rss" > a > li >
ul >
li >
< li class ="Closed" >< a href ="http://localhost/WSBLog/Catalog.aspx?cate=22" > 林业 (0) a >
< a href ="http://localhost/WSBLog/Rss.aspx?cate=22" target ="_blank" > < img src ="http://localhost/WSBLog/IMAGE/LOGO/rss.png" border ="0" alt ="rss" > a >
< ul >
< li class ="Child" >< a href ="http://localhost/WSBLog/Catalog.aspx?cate=23" > 林木的培育和种植 (0) a > < a href ="http://localhost/WSBLog/Rss.aspx?cate=23" target ="_blank" > < img src ="http://localhost/WSBLog/IMAGE/LOGO/rss.png" border ="0" alt ="rss" > a > li >< li class ="Child" >< a href ="http://localhost/WSBLog/Catalog.aspx?cate=27" > 木材和竹材的采运 (0) a > < a href ="http://localhost/WSBLog/Rss.aspx?cate=27" target ="_blank" > < img src ="http://localhost/WSBLog/IMAGE/LOGO/rss.png" border ="0" alt ="rss" > a > li >< li class ="Child" >< a href ="http://localhost/WSBLog/Catalog.aspx?cate=1202" > 林产品的采集 (0) a > < a href ="http://localhost/WSBLog/Rss.aspx?cate=1202" target ="_blank" > < img src ="http://localhost/WSBLog/IMAGE/LOGO/rss.png" border ="0" alt ="rss" > a > li >
ul >
li >
ul >
li > 
至于输出Html代码,这样写就是了:
' Blog目录索引重新时,会执行这个方法 
Public Sub BlogReBuild_Catalogs() Sub BlogReBuild_Catalogs()
Dim strCatalog As String = ""
Dim cates As TCategory() = GetTreeViewCategorys()
Dim sb As System.Text.StringBuilder = New System.Text.StringBuilder
If Not IsNothing(cates) Then
For Each cate As TCategory In cates
exportHtmlCategoryTree(cate, sb)
Next
End If
strCatalog = TransferHTML(sb.ToString(), "[no-asp]")
Call SaveToFile(System.IO.Path.Combine(BlogPath, "INCLUDE/catalog.asp"), strCatalog, "utf-8")
End Sub
'输出一颗目录树的html代码
Private Sub exportHtmlCategoryTree()Sub exportHtmlCategoryTree(ByVal cate As TCategory, ByRef sb As System.Text.StringBuilder)
Dim strClass As String = "Closed"
Dim hasChilds As Boolean = True
If cate.Childs Is Nothing Then
hasChilds = False
Else
If cate.Childs.Length = 0 Then
hasChilds = False
End If
End If
If Not hasChilds Then
strClass = "Child"
End If
sb.Append("
sb.Append(strClass)
sb.Append(""">")
sb.Append("" & cate.Url & """>" + cate.Name + " (" & cate.Count & ")" + "")
sb.Append(" " & BLOG_HOST & "Rss.aspx?cate=" & cate.ID.ToString() & """ target=""_blank"">")
sb.Append(" 
If hasChilds Then
sb.Append("
For Each child As TCategory In cate.Childs
'递归调用,输出子目录的Html代码
exportHtmlCategoryTree(child, sb)
Next
sb.Append("")
End If
sb.Append("
End Sub
当然,仅仅有了html代码还是不够的,可能还需要少量JavaScript和CSS的支持。网上讲怎么在Web中通过JavaScript和CSS实现树形目录的文章还是蛮多的,所以,这里就不多说了。大家可以google一下,或者可以参考这篇文章:
http://www.cnlei.org/mycode/CNLTreeMenu/Ver1.0.2/index.html
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
