由于文章的主体内容来自于飞鹰,只是我在Vs 2005下将其实现了。所以说转的吧,不过前面的是转的,后面的都是俺自己的体会了。

使用NHibernate开发主要有下面的四个步骤:

       创建实体层的类(Cool Coder工具生成)


       公用的数据层代码(使用写好的类)

       生成业务层的代码框架(使用QuickCode插件生成)

O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)//这步可以不用这个工具生成,手写也可以的
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
//当然也可以用它和一些代码生成工具如CodeSmith生成
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
//建议还是自己写的好些。

       测试代码

我们下面来一步一步看其实现的过程。

1)             创建实体层的类(工具生成)

       在菜单中选择New建立数据库连接。
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记) 

       选择要生成代码的表。

       设置生成代码的目录,单击生成。
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记) 

       查看生成结果,如下图:
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记) 

生成VB.NET代码如下:(相应的C#代码由CodeSmith生成)

Imports System

              public class  Customers

                            Public Sub New()//vb的空构造函数

                            End Sub 'New

                            private  _Region As System.String

                            Public Property Region() As System.String

                                          Get

                                                        return _Region

                                          End Get

                                          Set(ByVal Value As System.String)

                                                        _Region = Value

                                          End Set

                            End Property

 

                            private  _PostalCode As System.String

                            Public Property PostalCode() As System.String

                                          Get

                                                        return _PostalCode

                                          End Get

                                          Set(ByVal Value As System.String)

                                                        _PostalCode = Value

                                          End Set

                            End Property

 

                            private  _Fax As System.String

                            Public Property Fax() As System.String

                                          Get

                                                        return _Fax

                                          End Get

                                          Set(ByVal Value As System.String)

                                                        _Fax = Value

                                          End Set

                            End Property

 

                            private  _ContactName As System.String

                            Public Property ContactName() As System.String

                                          Get

                                                        return _ContactName

                                          End Get

                                          Set(ByVal Value As System.String)

                                                        _ContactName = Value

                                          End Set

                            End Property

 

                            private  _City As System.String

                            PublicPropertyCity() As System.String

                                          Get

                                                        return _City

                                          End Get

                                          Set(ByVal Value As System.String)

                                                        _City = Value

                                          End Set

                            End Property

 

                            private  _CustomerID As System.String

                            Public Property CustomerID() As System.String

                                          Get

                                                        return _CustomerID

                                          End Get

                                          Set(ByVal Value As System.String)

                                                        _CustomerID = Value

                                          End Set

                            End Property

 

                            private  _Address As System.String

                            Public Property Address() As System.String

                                          Get

                                                        return _Address

                                          End Get

                                          Set(ByVal Value As System.String)

                                                        _Address = Value

                                          End Set

                            End Property

 

                            private  _ContactTitle As System.String

                            Public Property ContactTitle() As System.String

                                          Get

                                                        return _ContactTitle

                                          End Get

                                          Set(ByVal Value As System.String)

                                                        _ContactTitle = Value

                                          End Set

                            End Property

 

                            private  _Phone As System.String

                            Public Property Phone() As System.String

                                          Get

                                                        return _Phone

                                          End Get

                                          Set(ByVal Value As System.String)

                                                        _Phone = Value

                                          End Set

                            End Property

 

                            private  _CompanyName As System.String

                            Public Property CompanyName() As System.String

                                          Get

                                                        return _CompanyName

                                          End Get

                                          Set(ByVal Value As System.String)

                                                        _CompanyName = Value

                                          End Set

                            End Property

 

                            private  _Country As System.String

                            Public Property Country() As System.String

                                          Get

                                                        return _Country

                                          End Get

                                          Set(ByVal Value As System.String)

                                                        _Country = Value

                                          End Set

                            End Property

End Class


生成的映射的
XML代码如下:

xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">

<class name="ORMDemo.Customers, ORMDemo" table="Customers">//注意这里,在代码中会用到。前面的是持久化类的全限定名,后面的是Assembly的名字。

<id name="CustomerID" column="CustomerID" type="String">

              <generator class="assigned" />

id>

<property name="CompanyName" type="String(40)" column="CompanyName" />

<property name="ContactName" type="String(30)" column="ContactName" />

<property name="ContactTitle" type="String(30)" column="ContactTitle" />

<property name="Address" type="String(60)" column="Address" />

<property name="City" type="String(15)" column="City" />

<property name="Region" type="String(15)" column="Region" />

<property name="PostalCode" type="String(10)" column="PostalCode" />

<property name="Country" type="String(15)" column="Country" />

<property name="Phone" type="String(24)" column="Phone" />

<property name="Fax" type="String(24)" column="Fax" />

class>

hibernate-mapping>

       创建一个空的项目,把代码拷贝进去。

       参照Nhibenate DLL

       你现在就可以使用他们来执行数据库的操作了。

 

2)             公用的数据层代码(使用写好的类)

我们这里使用一个写好的数据库层的访问数据库方法,这样,数据层将不需要再增加任何代码。数据层通用访问方法如下:

//VB 代码
Imports
System

Imports System.Reflection

Imports System.Data

Imports System.Data.SqlClient

 

Imports NHibernate

Imports NHibernate.Cfg

Imports NHibernate.Dialect

Imports NHibernate.Tool.hbm2ddl

 

 

Public Class EntityControl

    Private Shared entity As EntityControl

 

    Protected Shared myCfg As NHibernate.Cfg.Configuration

    Protected Shared dialect As NHibernate.dialect.Dialect

    Protected Shared sessions As ISessionFactory

 

    Public Shared Function CreateControl() As EntityControl

        If entity Is Nothing Then

            BuildSessionFactory()

            If entity Is Nothing Then

                entity = New EntityControl

            End If

        End If

        Return entity

    End Function 'CreateControl

 

    Private Shared Sub BuildSessionFactory()

        ExportSchema(New String() {"Customers.hbm.xml"}, False)

    End Sub 'BuildSessionFactory

 

    Public Sub AddEntity(ByVal entity As Object)

 

        Dim s As ISession = sessions.OpenSession()

        Dim t As ITransaction = s.BeginTransaction()

        Try

            s.Save(entity)

            t.Commit()

        Catch e As Exception

            t.Rollback()

            Throw e

        Finally

            s.Close()

        End Try

    End Sub 'AddEntity

 

 

    Public Sub UpdateEntity(ByVal entity As Object, ByVal key As Object)

        Dim s As ISession = sessions.OpenSession()

        Dim t As ITransaction = s.BeginTransaction()

        Try

            s.Update(entity, key)

            t.Commit()

        Catch e As Exception

            t.Rollback()

            Throw e

        Finally

            s.Close()

        End Try

    End Sub 'UpdateEntity

 

    Public Sub DeleteEntity(ByVal entity As Object)

        Dim s As ISession = sessions.OpenSession()

        Dim t As ITransaction = s.BeginTransaction()

        Try

            s.Delete(entity)

            t.Commit()

        Catch e As Exception

            t.Rollback()

            Throw e

        Finally

            s.Close()

        End Try

    End Sub 'DeleteEntity

 

 

    Public Function GetEntities(ByVal query As String) As IList

        Dim lst As IList

        Dim s As ISession = sessions.OpenSession()

        Dim t As ITransaction = s.BeginTransaction()

 

        lst = s.Find(query)

        t.Commit()

        s.Close()

        Return lst

    End Function 'GetEntities

 

    Public Function GetEntity(ByVal theType As System.Type, ByVal id As Object) As Object

 

        Dim obj As Object

        Dim s As ISession = sessions.OpenSession()

        Dim t As ITransaction = s.BeginTransaction()

        obj = s.Load(theType, id)

        t.Commit()

        s.Close()

 

        Return obj

    End Function 'GetEntity

 

 

    Private Overloads Shared Sub ExportSchema(ByVal files() As String) '

 

        ExportSchema(files, True)

    End Sub 'ExportSchema

 

    Private Overloads Shared Sub ExportSchema(ByVal files() As String, ByVal exportSchema As Boolean)

        myCfg = New NHibernate.Cfg.Configuration

        Dim i As Integer

        For i = 0 To files.Length - 1

            myCfg.AddResource("ORMDemo." + files(i), [Assembly].Load("ORMDemo"))

        Next i

        If exportSchema Then

            Dim se As New SchemaExport(myCfg)

            se.Create(True, True)

        End If

        sessions = myCfg.BuildSessionFactory()

        dialect = NHibernate.Dialect.Dialect.GetDialect()

    End Sub 'ExportSchema

 

    '/

    '/ Drops the schema that was built with the TestCase's Configuration.

    '/

    Private Shared Sub DropSchema()

        Dim se As New SchemaExport(myCfg)

        se.Drop(True, True)

    End Sub 'DropSchema

 

    Private Overloads Shared Sub ExecuteStatement(ByVal sql As String)

        ExecuteStatement(sql, True)

    End Sub 'ExecuteStatement

 

    Private Overloads Shared Sub ExecuteStatement(ByVal sql As String, ByVal [error] As Boolean)

        Dim conn As IDbConnection = Nothing

        Dim tran As IDbTransaction = Nothing

        Try

            If myCfg Is Nothing Then

                myCfg = New NHibernate.Cfg.Configuration

            End If

            Dim prov As NHibernate.Connection.IConnectionProvider = NHibernate.Connection.ConnectionProviderFactory.NewConnectionProvider(myCfg.Properties)

            conn = prov.GetConnection()

            tran = conn.BeginTransaction()

            Dim comm As IDbCommand = conn.CreateCommand()

            comm.CommandText = sql

            comm.Transaction = tran

            comm.CommandType = CommandType.Text

            comm.ExecuteNonQuery()

            tran.Commit()

        Catch exc As Exception

            If Not (tran Is Nothing) Then

                tran.Rollback()

            End If

            If [error] Then

                Throw exc

            End If

        Finally

            If Not (conn Is Nothing) Then

                conn.Close()

            End If

        End Try

    End Sub 'ExecuteStatement

 

End Class 'EntityControl


 

相应的C#代码如下:

O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)using System;
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
using System.Data;
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
using System.Configuration;
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
using System.Web;
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
using System.Web.Security;
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
using System.Web.UI;
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
using System.Web.UI.WebControls;
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
using System.Web.UI.WebControls.WebParts;
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
using System.Web.UI.HtmlControls;
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
using NHibernate;
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
using NHibernate.Cfg;
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
using NHibernate.Dialect;
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
using NHibernate.Tool.hbm2ddl;
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
using Iesi.Collections ;
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
using System.Reflection;
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
using System.Collections;
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)
O/R Mapping 研究报告(5) --- 使用NHibernate进行开发--Vs 2005 C# (转自 飞鹰手记)

 

3)             生成业务层的代码框架(使用QuickCode插件生成)

我们使用QuickCode可以自动生成,业务层的增删改框架,我们只需要增加业务处理的功能即可。

自动生成的业务层代码如下:

'------------------------------------------------------------------------

' Copyright (C) 2000-2004 GrapeCity Corporation

' All rights reserved.

'

' Description:

'   Customer class

'

' Created By:       Tim Wang

' Date Created:     21-09-2004

'

' Modified History:

' Date          By                  Description

' ----------    ----------------    -------------------------------------

'------------------------------------------------------------------------

 

Public Class CustomerBR

    Dim control As EntityControl

    Sub New()//VB的构造函数

        control = EntityControl.CreateControl()

    End Sub

    '-------------------------------------------------------------------------

    ' Name: Add

    '

    ' Description:  The Add method is used to Add Customer in BusinessRule layer.

    '

    ' Created By:       Tim Wang

    ' Date Created:     21-09-2004

    '--------------------------------------------------------------------------

    Public Sub Add(ByVal Customer As Customers)

        Check(Customer)

        control.AddEntity(Customer)

    End Sub

    '-------------------------------------------------------------------------

    ' Name: Update

    '

    ' Description:  The Update method is used to Update Customer in BusinessRule layer.

    '

    ' Created By:       Tim Wang

    ' Date Created:     21-09-2004

    '--------------------------------------------------------------------------

    Public Sub Update(ByVal Customer As Customers)

        control.UpdateEntity(Customer, Customer.CustomerID)

    End Sub

    '-------------------------------------------------------------------------

    ' Name: Delete

    '

    ' Description:  The Delete method is used to Delete Customer in BusinessRule layer.

    '

    ' Created By:       Tim Wang

    ' Date Created:     21-09-2004

    '--------------------------------------------------------------------------

    Public Sub Delete(ByVal Customer As Customers)

        control.DeleteEntity(Customer)

    End Sub

 

    '-------------------------------------------------------------------------

    ' Name: GetCustomers

    '

    ' Description:  The GetCustomers method is used to Get Customers in BusinessRule layer.

    '

    ' Created By:       Tim Wang

    ' Date Created:     21-09-2004

    '--------------------------------------------------------------------------

    Public Function GetCustomers(ByVal query As String) As IList

        Return control.GetEntities(query)

    End Function

 

    '-------------------------------------------------------------------------

    ' Name: GetSingleCustomer

    '

    ' Description:  The GetSingleCustomer method is used to Get a single Customer in BusinessRule layer.

    '

    ' Created By:       Tim Wang

    ' Date Created:     21-09-2004

    '--------------------------------------------------------------------------

    Public Function GetSingleCustomer(ByVal CustomerID As String) As Customers

        Return CType(control.GetEntity(GetType(Customers), CustomerID), Customers)

    End Function

 

    Private Sub Check(ByVal Customer As Customers)

    End Sub

End Class

 

 

我们留一个Check方法来做业务数据的检查。(把这个函数直接写入上面的空函数中即可

如下:

    Private Sub Check(ByVal Customer As Customers)

        If Customer.CustomerID = "911" Then

            Throw New ApplicationException("911 is not suitable to be used to CustomerID.")

        End If

    End Sub

 

 

4)             测试代码

 

我们来编写调用的测试代码,如下:

Imports NUnit.Framework

 

_

()>

Public Class TestCustomer

 

    Dim Cust As CustomerBR

    Dim customer As Customers

    Dim customerID As String

    _

()>

    Public Sub init()

        Cust = New CustomerBR

        customerID = "003"

 

    End Sub

    _

()>

    Public Sub Add()

        customer = New Customers

        Dim count As Integer

        count = Cust.GetCustomers("from c in class Customers").Count

        With customer

            .CustomerID = customerID

            .CompanyName = "GPCT"

            .Country = "China"

        End With

        Cust.Add(customer)

        Assert.AreEqual(count + 1, Cust.GetCustomers("from c in class Customers").Count)

    End Sub

    _

()>

    Public Sub Modify()

        customer = Cust.GetSingleCustomer(customerID)

        Assert.AreEqual("China", customer.Country)

        customer.Country = "Japan"

        Cust.Update(customer)

 

        customer = Cust.GetSingleCustomer(customerID)

 

        Assert.IsFalse(customer.Country = "China")

 

        Assert.AreEqual("Japan", customer.Country)

    End Sub

 

    _

()>

    Public Sub Delete()

        customer = New Customers

        customer.CustomerID = customerID

 

        Assert.AreEqual(1, Cust.GetCustomers("from c in class Customers where c.CustomerID = '" & customerID & "'").Count)

        Cust.Delete(customer)

 

        Assert.AreEqual(0, Cust.GetCustomers("from c in class Customers where c.CustomerID = '" & customerID & "'").Count)

 

    End Sub

 

    GetType(),>(ApplicationException))> _

    Public Sub TestBusinessRule()

        customer = New Customers

      

        With customer

            .CustomerID = "9111"

            .CompanyName = "GPCT"

            .Country = "China"

        End With

        Cust.Add(customer)

    End Sub

 

End Class

 

5)             数据库字段修改演示

我们把Customers表中的Country字段修改为country1,这时候测试代码失败。修改xml文件,再运行测试代码,程序通过。

 

结论:我们修改字段名称时,只需要修改XML文件即可,程序不做任何改动。

 

6)             数据库字段增加演示

我们在数据库中增加一字段aaa,重新生成实体类和XML文件,即可使用新的实体类,程序不需要做任何改变。

 

结论:修改字段时只在需要增加新字段的内容的地方作修改,不需要增加任何其他代码。

 

7)             数据库字段删除演示

我们删除一列,重新生成实体类和XML文件,程序会在需要修改的地方提示,只要删除此除代码即可,其它程序不做任何改动。

 

8)             把结果转变成DataSet

如果想把返回的IList转变成DataSet,我们只要调一个通用的方法即可,而如果想从DataSet转变成实体类组成的IList,将会非常复杂。

 

转换成DataSet的通用的方法如下:

    Private Function ConvertToDS(ByVal lst As IList, ByVal typ As System.Type) As DataSet

        Dim obj As Object

        Dim ds As New DataSet

 

        Dim tbl As DataTable = ds.Tables.Add(typ.Name)

 

        ' Get the public properties.

        Dim myPropertyInfo As System.Reflection.PropertyInfo() = typ.GetProperties((System.Reflection.BindingFlags.Public Or System.Reflection.BindingFlags.Instance))

 

 

        Dim pi As System.Reflection.PropertyInfo

        For Each pi In myPropertyInfo

            tbl.Columns.Add(pi.Name, System.Type.GetType(pi.PropertyType.ToString()))

        Next

 

 

        For Each obj In lst

            Dim dr As DataRow = tbl.NewRow

 

            For Each pi In myPropertyInfo

                dr(pi.Name) = pi.GetValue(obj, Nothing)

            Next

            tbl.Rows.Add(dr)

 

        Next

        Return ds

    End Function

使用上面的方法来生成DataSet的方法如下:

Dim Cust As New CustomerBR

Dim customerLst As IList

customerLst = Cust.GetCustomers("from Customers")

 

Dim myType As System.Type = GetType(Customers)

DataGrid1.DataSource = ConvertToDS(customerLst, myType).Tables(0

相关文章:

  • 2021-08-21
  • 2021-09-26
  • 2021-06-26
  • 2021-12-29
  • 2022-03-11
  • 2022-03-02
  • 2021-06-08
猜你喜欢
  • 2021-06-26
  • 2022-12-23
  • 2021-10-01
  • 2022-01-15
  • 2021-09-02
  • 2022-12-23
  • 2022-03-09
相关资源
相似解决方案