摘要

在实际的项目中,经常是将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对象。

NHibernate系列文章十六:使用程序集管理NHibernate项目(附程序下载)的更多相关文章

  1. NHibernate系列文章十:NHibernate对象二级缓存下

    摘要 上一节对NHibernate二级缓存做了简单介绍,NHibernate二级缓存是由SessionFactory管理的,所有Session共享.这一节介绍二级缓存其他两个方面:二级缓存查询和二级缓 ...

  2. NHibernate系列文章十九:NHibernate关系之多对多关系(附程序下载)

    摘要 NHibernate的多对多关系映射由many-to-many定义. 从这里下载本文的代码NHibernate Demo 1.修改数据库 添加Product表 添加ProductOrder表 数 ...

  3. NHibernate系列文章十五:NHibernate组件

    摘要 前面文章介绍了NHibernate对简单.net数据类型的映射对照表.NHibernate也可以映射复杂数据类型,这里介绍通过组件映射NHibernate值对象. 1. NHibernate引用 ...

  4. NHibernate系列文章十八:NHibernate关系之一对多(附程序下载)

    摘要 这篇文章介绍NHibernate最实用的内容:关系映射. NHibernate的关系映射方式有三种: Set:无序对象集合,集合中每一个元素不能重复. List:有序对象集合,集合中的元素可以重 ...

  5. NHibernate系列文章十二:Load/Get方法

    摘要 NHibernate提供两个方法按主键值查找对象:Load/Get. 1. Load/Get方法的区别 Load: Load方法可以对查询进行优化. Load方法实际得到一proxy对象,并不立 ...

  6. NHibernate系列文章十四:NHibernate事务

    摘要 NHibernate实现事务机制非常简单,调用ISession.BeginTransaction()开启一个事务对象ITransaction,使用ITransaction.Commit()提交事 ...

  7. Web 前端开发人员和设计师必读精华文章【系列二十六】

    <Web 前端开发精华文章推荐>2014年第5期(总第26期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  8. NHibernate系列文章目录

    第一章:NHibernate基础 NHibernate介绍 第一个NHibernate工程 简单的增删改查询 运行时监控 NHibernate配置 数据类型映射 Get/Load方法 NHiberna ...

  9. linux基础-第十六单元 yum管理RPM包

    第十六单元 yum管理RPM包 yum的功能 本地yum配置 光盘挂载和镜像挂载 本地yum配置 网络yum配置 网络yum配置 Yum命令的使用 使用yum安装软件 使用yum删除软件 安装组件 删 ...

随机推荐

  1. 对hbase的学习

    HBase,是Hadoop DataBase. 面向列的分布式数据库, 思想来源于Google的BigTable思想,它的目标是在廉价硬件构成的集群上管理超大规模的稀疏表. Hbase的物理结构 HB ...

  2. js 实现继承相关

    ☊ [要求]:实现一个Animal类, 和一个继承它的Dog类 ☛ [实现]: function Animal(name) { this.name = name; } Animal.prototype ...

  3. Runloop之个人理解

    Runloop之个人理解更像是一种线程等待机制,传统线程的消息传入机制,线程收到什么样的消息,就执行什么样的动作,如果是信号量队列型的,其实就基本实现了线程在无消息时挂住休眠;而不是在每隔一段时间就要 ...

  4. 将war包部署到服务器的详细步骤

    第一步: 先将项目打包成war文件,也就是将在项目上单击鼠标右键,选择Export: 选择WAR file,点击下一步: 会出现如下所示,选择你要保存的位置,点击完成: 在你所选择的地方会有个如下所示 ...

  5. hdu4691 Front compression ——暴力 || 后缀数组

    link:http://acm.hdu.edu.cn/showproblem.php?pid=4691 暴力,数据明显太水了吧,n=10^5, O(n^2)的复杂度哎喂.想让大家暴力写直接让n=100 ...

  6. Django中ImageField的使用

    http://blog.csdn.net/u013690521/article/details/38777213 from django.db import models from django.co ...

  7. 2017.1.8a版给信息源新增:max_len、max_db字段

    2017.1.8a版程序给信息源增加max_len.max_db字段,分别用于控制:获取条数.数据库保留条数. max_len的说明见此图: max_db的说明见此图: 当max_len和max_db ...

  8. maxscript, 批量导出物体

    1,将场景中所有选中物体整体导出为一个fbx文件 exportfile filename #noprompt selectedOnly:true using:FBXEXP 2,将场景中所有选中物体各导 ...

  9. Appium使用PageFactory初始化对象时报空指针错误

    自己的测试框架里面,每个app页面都要初始化appium field,所以想到使用一个静态的变量,后来初始化一个页面对象时总是报空指针. 在网上找了好多材料,看着没有什么区别.后来在github上面看 ...

  10. 【linux】三十分钟学会AWK

    本文大部分内容翻译自我开始学习AWK时看到的一篇英文文章 AWK Tutorial ,觉得对AWK入门非常有帮助,所以对其进行了粗略的翻译,并对其中部分内容进行了删减或者补充,希望能为对AWK感兴趣的 ...