摘要
在实际的项目中,经常是将NHibernate的实体关系映射类做成独立的工程(assembly dll),只对外提供Session调用的接口。这个程序集作为数据访问层,可以被上面的多个工程(ASP.Net、Windows Form、Windows Serviice等)调用。
这篇文章介绍如何设计NHibernate数据访问层的工程,以及如何架构数据访问层和上面的应用层的关系。
本文章的所有代码可以到第一个NHibernate程序下载。
步骤:
1)为了后面文章的程序演示方便,删除Customer表,新建主键类型是int类型,主键生成方法是IDENTITY的Customer表。
CREATE TABLE [dbo].[Customer](
[Id] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [nvarchar](10) NOT NULL,
[LastName] [nvarchar](10) NOT NULL,
[Points] [int] NULL,
[HasGoldStatus] [bit] NULL,
[MemberSince] [date] NULL,
[CreditRating] [nchar](20) NULL,
[AverageRating] [decimal](18, 4) NULL,
[Street] [nvarchar](100) NULL,
[City] [nvarchar](100) NULL,
[Province] [nvarchar](100) NULL,
[Country] [nvarchar](100) NULL,
CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
2)添加Class Library:NHibernateDemoAPP.XML.Entities。删除Class1.cs文件。
这里使用XML映射,因此这里用NHibernateDemoAPP.XML.Entities作为工程名。实际项目的工程名称应该没有"XML"。
3)在NHibernateDemoAPP.XML.Entities工程里添加文件夹Domain和hbm。也可以创建名称为Mapping的文件夹,替代这里的hbm文件夹,看个人喜好。
4)将NHibernateDemoApp工程的文件Address.cs、Customer.cs移动到Domain文件夹。将文件Customer.hbm.xml移动到hbm文件夹。在NHibernateDemoApp工程里删除文件Address.cs、Customer.cs和Customer.hbm.xml。
5)修改NHibernateDemoApp工程的文件hibernate.hbm.xml。修改mapping节点的assembly属性。
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.connection_string_name">default</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
<mapping assembly="NHibernateDemoAPP.XML.Entities"/>
</session-factory>
</hibernate-configuration>
6)修改Customer.cs的namespace。将Id属性改成int。
using System; namespace NHibernateDemoAPP.XML.Entities.Domain
{
public class Customer
{
public virtual int Id { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual double AverageRating { get; set; }
public virtual int Points { get; set; }
public virtual bool HasGoldStatus { get; set; }
public virtual DateTime MemberSince { get; set; }
public virtual CustomerCreditRating CreditRating { get; set; }
public virtual Address Address { get; set; }
} public enum CustomerCreditRating
{
Excellent, VeryVeryGood, VeryGood, Good, Neutral, Poor, Terrible
}
}
7)修改Customer.hbm.xml文件。修改根节点hibernate-mapping的assembly属性和namespace属性。
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateDemoAPP.XML.Entities" namespace="NHibernateDemoAPP.XML.Entities.Domain">
<class name="Customer" table="Customer">
<id name="Id">
<generator class="native"/>
</id>
<property name="FirstName" not-null="true"/>
<property name="LastName" not-null ="true"/>
<property name="AverageRating"/>
<property name="Points"/>
<property name="HasGoldStatus"/>
<property name="MemberSince"/>
<property name="CreditRating" type="CustomerCreditRating"/>
<component name="Address">
<property name="Street"/>
<property name="City"/>
<property name="Province"/>
<property name="Country"/>
</component>
</class>
</hibernate-mapping>
8)为工程NHibernateDemoApp添加工程NHibernateDemoAPP.XML.Entities的引用。
9)修改Program.cs文件。
using NHibernate;
using NHibernate.Cfg;
using NHibernateDemoAPP.XML.Entities.Domain;
using System;
using System.Collections.Generic; namespace NHibernateDemoApp
{
class Program
{
private static ISessionFactory _sessionFactory; private static ISession _session; public static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
{
var cfg = new Configuration();
cfg.Configure();
_sessionFactory = cfg.BuildSessionFactory();
}
return _sessionFactory;
}
} public static ISession Session
{
get
{
if (_session == null)
{
_session = SessionFactory.OpenSession();
}
return _session;
}
} static void Main(string[] args)
{
HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); using (var session = SessionFactory.OpenSession())
{
var customer = CreateCustomer();
object custoemrId = session.Save(customer);
session.Flush(); customer = session.Get<Customer>(custoemrId);
Console.WriteLine(customer.LastName);
} Console.WriteLine("Completed");
Console.ReadLine();
} private static Customer CreateCustomer()
{
var customer = new Customer
{
FirstName = "Daniel",
LastName = "Tang",
Points = ,
HasGoldStatus = true,
MemberSince = new DateTime(, , ),
CreditRating = CustomerCreditRating.Good,
AverageRating = 42.42424242,
Address = new Address
{
Street = "123 Somewhere Avenue",
City = "Nowhere",
Province = "Alberta",
Country = "Canada"
}
}; return customer;
} private static void UpdateInTransaction(Customer customer)
{
using (var transaction = Session.BeginTransaction())
{
try
{
Session.Update(customer);
transaction.Commit();
}
catch (HibernateException e)
{
transaction.Rollback();
throw e;
}
}
} private static IList<Customer> GetAll()
{
using (var session = SessionFactory.OpenSession())
{
IList<Customer> list = session.CreateCriteria<Customer>().List<Customer>();
return list;
}
} private static Customer GetById(Guid id)
{
using (var session = SessionFactory.OpenSession())
{
Customer customer = session.Get<Customer>(id);
return customer;
}
} private static Customer LoadById(Guid id)
{
using (var session = SessionFactory.OpenSession())
{
Customer customer = session.Load<Customer>(id);
return customer;
}
} private static int Insert(Customer customer)
{
using (var session = SessionFactory.OpenSession())
{
var identifier = session.Save(customer);
session.Flush();
return Convert.ToInt32(identifier);
}
} private static void Update(Customer customer)
{
using (var session = SessionFactory.OpenSession())
{
session.SaveOrUpdate(customer);
session.Flush();
}
} private static void Delete(int id)
{
using (var session = SessionFactory.OpenSession())
{
var customer = session.Get<Customer>(id);
session.Delete(customer);
session.Flush();
}
}
}
}
9)执行程序,将一条Customer对象插入到数据库记录中。
下一篇文章介绍如何在应用层(ASP.Net MVC, ASP.Net Web, Windows Form, Windows Service)中管理SessionFactory对象和Session对象。