[Fluent NHibernate]第一个程序

目录

写在前面

Fluent Nhibernate简介

基本配置

总结

写在前面

耗时两月,NHibernate系列出炉这篇文章中,很多园友说了Fluent Nhibernate的东东,也激起我的兴趣,想对它一探究竟,这里也将Fluent Nhibernate写成一个系列,记录自己的学习过程,关于这东东,也是第一次接触,也只能边摸索,边记录了。如果有描述错误的地方,还望多多包涵。

通过Nhibernate的学习,都觉得Nhibernate的使用映射文件的编写很麻烦,这里通过Fluent Nhibernate的进行对比学习。

Fluent Nhibernate简介

Fluent Nhibernate下载地址:http://www.fluentnhibernate.org/

在该网站上对Fluent Nhibernate的简介

Fluent, XML-less, compile safe, automated, convention-based mappings for NHibernate.

Fluent,更少的xml,编译安全,自动化,基于Nhibernate的映射。

Fluent NHibernate offers an alternative to NHibernate‘s standard XML mapping files. Rather than writing XML documents (.hbm.xml files), Fluent NHibernate lets you write mappings in strongly typed C# code. This allows for easy refactoring, improved readability and more concise code.

用编程的方式进行配置,让你能更好的理解,不需要编写复杂的映射文件,它能完全替换NHibernate的映射文件,让你在映射的时候能使用C#的强类型方式。

基本配置

测试项目结构

项目结构介绍

Wolfy.Data:项目数据层,存放操作数据库类,FluentNhibernateHelper

Wolfy.Domain:存放持久化类,及映射类。

Wolfy.UnitTest:单元测试项目

首先使用Nuget安装Fluent Nhibernate

安装成功后

Fluent Nhibernate是基于Nhibernate的,所以在安装Fluent Nhibernate的同时也会将Nhibernate的dll安装上。此时的Nhibernate的程序集的版本为

Fluent Nhibernate对应的Nhibernate版本为3.3.1.4000

编写FluentNhibernateHelper类

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using NHibernate;
 7 using FluentNHibernate;
 8 namespace Wolfy.Data
 9 {
10     /// <summary>
11     /// Nhibernate辅助类
12     /// </summary>
13     public class FluentNHibernateHelper
14     {
15         private static ISessionFactory _sessionFactory;
16         private static ISession _session;
17         private static object _objLock = new object();
18         private FluentNHibernateHelper()
19         {
20
21         }
22         /// <summary>
23         /// 创建ISessionFactory
24         /// </summary>
25         /// <returns></returns>
26         public static ISessionFactory GetSessionFactory()
27         {
28             if (_sessionFactory == null)
29             {
30                 lock (_objLock)
31                 {
32                     if (_sessionFactory == null)
33                     {
34                         //配置ISessionFactory
35                         _sessionFactory = FluentNHibernate.Cfg.Fluently.Configure()
36                             //数据库配置
37                 .Database(
38                             //方言
39                 FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2012
40                             //连接字符串
41                 .ConnectionString(
42                      c => c.Server(".")
43                     .Password("sa")
44                     .Username("sa")
45                     .Database("Shop")
46                     .TrustedConnection()
47                     )
48                             //是否显示sql
49                     .ShowSql()
50                     )
51                             //映射程序集
52                     .Mappings(m => m.FluentMappings
53                         .AddFromAssembly(System.Reflection.Assembly.Load("Wolfy.Domain"))
54                         .ExportTo("c:\\"))
55                     .BuildSessionFactory();
56
57                     }
58                 }
59             }
60             return _sessionFactory;
61
62         }
63         /// <summary>
64         /// 重置Session
65         /// </summary>
66         /// <returns></returns>
67         public static ISession ResetSession()
68         {
69             if (_session.IsOpen)
70                 _session.Close();
71             _session = _sessionFactory.OpenSession();
72             return _session;
73         }
74         /// <summary>
75         /// 打开ISession
76         /// </summary>
77         /// <returns></returns>
78         public static ISession GetSession()
79         {
80              GetSessionFactory();
81             if (_session == null)
82             {
83                 lock (_objLock)
84                 {
85                     if (_session == null)
86                     {
87                         _session = _sessionFactory.OpenSession();
88                     }
89                 }
90             }
91             return _session;
92         }
93
94     }
95 }

CreateSessionFactory方法对应Nhibernate的配置文件,通过代码的方式指定Nhibernate的配置信息,使用起来更方便。下面为之前学习Nhibernate时写的配置文件,不明白的可以回到NHIbernate系列文章去查看。

 1 <?xml version="1.0" encoding="utf-8" ?>
 2  <hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
 3     <session-factory>
 4     <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
 5    <property name="connection.connection_string">
 6        server=.;database=shop;uid=sa;pwd=sa
 7   </property>
 8    <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
 9   <mapping  assembly="Wolfy.Shop.Domain"/>
10   </session-factory>
11   </hibernate-configuration>

一个例子

Customer持久化类

 1     /// <summary>
 2     /// 客户持久化类
 3     /// </summary>
 4     public class Customer
 5     {
 6         public virtual Guid CustomerID { set; get; }
 7         public virtual int Version { set; get; }
 8         public virtual string CustomerName { set; get; }
 9         public virtual string CustomerAddress { set; get; }
10     }

添加映射类

CustomerMapping.cs

 1    /// <summary>
 2     /// Customer映射实体类,需要集成ClassMap泛型类
 3     /// </summary>
 4     public class CustomerMapping : ClassMap<Customer>
 5     {
 6         /// <summary>
 7         /// 映射关系实体类的构造函数
 8         /// 在构造函数中处理好映射关系
 9         /// </summary>
10         public CustomerMapping()
11         {
12             //指定持久化类对应的数据表
13             Table("TB_Customer");
14             //自动增长的id
15             //Id(i => i.CustomerID);
16             //映射关系
17             Id<Guid>("CustomerID").GeneratedBy.Guid();
18             Map(m => m.CustomerAddress).Length(50).Nullable();
19             Map(m => m.CustomerName).Length(32).Nullable();
20             Map(m => m.Version);
21         }
22     }

映射配置类需继承ClassMap泛型类,在构造函数中可以通过Map方法,指定字段与数据表字段的对应关系,Map有两个重载方法,如下:

 1         //
 2         // 摘要:
 3         //     Create a property mapping.
 4         //
 5         // 参数:
 6         //   memberExpression:
 7         //     Property to map
 8         public PropertyPart Map(Expression<Func<T, object>> memberExpression);
 9         //
10         // 摘要:
11         //     Create a property mapping.
12         //
13         // 参数:
14         //   memberExpression:
15         //     Property to map
16         //
17         //   columnName:
18         //     Property column name
19         public PropertyPart Map(Expression<Func<T, object>> memberExpression, string columnName);

Map

这里有个需要注意的地方,如果不指定映射的数据表,默认持久化类要与数据库中的表名对应,比如持久化类名为Customer,而数据表名为TB_Customer,则有以下异常: could not execute batch command.[SQL: SQL not available]

意思就是对应关系找不到。解决办法就是指定映射的数据表名。

数据层CustomerData类添加AddCustomer方法

 1     /// <summary>
 2     /// 客户类数据层
 3     /// </summary>
 4     public class CustomerData
 5     {
 6         /// <summary>
 7         /// 添加客户对象
 8         /// </summary>
 9         /// <param name="customer"></param>
10         /// <returns></returns>
11         public bool AddCustomer(Customer customer)
12         {
13             ISession session = FluentNHibernateHelper.GetSession();
14             using (var trans = session.BeginTransaction())
15             {
16                 try
17                 {
18                     session.SaveOrUpdate(customer);
19                     session.Flush();
20                     trans.Commit();
21                     return true;
22                 }
23                 catch (Exception)
24                 {
25                     trans.Rollback();
26                     return false;
27                 }
28             }
29
30         }
31     }

你会发现,方法与使用Nhibernate的时候的方法实现没什么区别,代码相同,唯一的区别就是配置文件的编写方式,一种是使用代码实现,一种是使用xml文件进行配置的。

单元测试

 1 using System;
 2 using Microsoft.VisualStudio.TestTools.UnitTesting;
 3 using Wolfy.Domain.Entities;
 4 using Wolfy.Data;
 5 namespace Wolfy.UnitTest
 6 {
 7     [TestClass]
 8     public class CustomerDataTest
 9     {
10         private CustomerData _customerData;
11         public CustomerDataTest()
12         {
13             _customerData = new CustomerData();
14         }
15         [TestMethod]
16         public void AddCustomerTest()
17         {
18             var result = _customerData.AddCustomer(
19                 new TB_Customer()
20                 {
21                     Version = 1,
22                     CustomerName = "wolfy",
23                     CustomerAddress = "中国 北京",
24                     CustomerID = Guid.NewGuid()
25                 }
26                 );
27             Assert.IsTrue(result);
28         }
29     }
30 }

描述:通过数据层的AddCustomer方法向数据库中添加一个客户对象,并获得添加结果,断言结果为true,则测试通过。
运行测试,测试结果

生成的sql语句

 1 exec sp_executesql N‘INSERT INTO [TB_Customer]
 2 (CustomerAddress, CustomerName, Version, CustomerID)
 3 VALUES (@p0, @p1, @p2, @p3)‘,
 4 N‘@p0 nvarchar(4000),
 5 @p1 nvarchar(4000),
 6 @p2 int,
 7 @p3 uniqueidentifier‘,
 8 @p0=N‘中国 北京‘,
 9 @p1=N‘wolfy‘,
10 @p2=1,
11 @p3=‘F15D04CF-300F-45C1-A774-3394CBA08155‘

回头看一下,在FluentNhibernateHelper中,有这样一句代码:

1                         //映射程序集
2                     .Mappings(m => m.FluentMappings
3                         .AddFromAssembly(System.Reflection.Assembly.Load("Wolfy.Domain"))
4                         .ExportTo("c:\\"))

意思是将映射文件导出到c盘下,那么我们看一下c盘下生成了什么?

你会发现此时的xml文件正是Nhibernate中对应持久化类的映射文件,内容为:

 1 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
 2   <class xmlns="urn:nhibernate-mapping-2.2" name="Wolfy.Domain.Entities.Customer, Wolfy.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="TB_Customer">
 3     <id type="System.Guid, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
 4       <column name="CustomerID" />
 5       <generator class="guid" />
 6     </id>
 7     <property name="CustomerAddress" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
 8       <column name="CustomerAddress" length="50" not-null="false" />
 9     </property>
10     <property name="CustomerName" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
11       <column name="CustomerName" length="32" not-null="false" />
12     </property>
13     <property name="Version" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
14       <column name="Version" />
15     </property>
16   </class>
17 </hibernate-mapping>

总结

关于Fluent Nhibernate的基本使用就介绍到这里,不管怎样,先让第一个程序跑起来,才算是走好了第一步。

本篇内容学习了如何使用Fluent Nhibernate生成配置文件及映射文件。

参考文章

http://www.cnblogs.com/inday/archive/2009/08/04/Study-Fluent-NHibernate-Start.html

时间: 2024-10-20 19:49:57

[Fluent NHibernate]第一个程序的相关文章

[Fluent NHibernate]一对多关系处理

目录 写在前面 系列文章 一对多关系 总结 写在前面 上篇文章简单介绍了,Fluent Nhibernate使用代码的方式生成Nhibernate的配置文件,以及如何生成持久化类的映射文件.通过上篇的学习你会发现,Fluent Nhibernate仍然需要引用Nhibernate的两个程序集(Nhibernate.dll和Iesi.Collections.dll),所以与Nhibernate最大的区别就在生成配置文件的方式上面,这里关于Nhibernate的特性方面就不再多赘述,可以参考Nhib

NHibernate系列文章二十七:NHibernate Mapping之Fluent Mapping(附程序下载)

摘要 从这一节起,介绍NHibernate Mapping的内容.前面文章都是使用的NHibernate XML Mapping.NHibernate XML Mapping是NHibernate最早最成熟的Mapping方法.其他的Mapping方法都是基于XML Mapping的思想进行的“变种”,要么暂时不能完全像XML Mapping那样功能丰富.其他的Mapping方法目前包括:Fluent Mapping.Attribute Mapping和Mapping by Convention

【翻译】首个基于NHibernate的应用程序

首个基于NHibernate的应用程序  Your first NHibernate based application 原文地址:http://www.nhforge.org/wikis/howtonh/your-first-nhibernate-based-application.aspx 本文涉及到的DEMO下载   定义领域模型 让我们开始通过定义一个非常简单的领域模型.目前它是由一个称为产品的实体.该产品具有 3 个属性:名称. 类别和中止. 添加一个文件夹 Domain 到您的解决方

【翻译】Fluent NHibernate介绍和入门指南

英文原文地址:https://github.com/jagregory/fluent-nhibernate/wiki/Getting-started 翻译原文地址:http://www.cnblogs.com/13yan/p/5685307.html 入门指南 Fluent NHibernate 概述 Fluent NHibernate 提供一个替代 NHibernate 的标准 XML 映射文件的方法.而不是编写 XML 文档 (.hbm.xml 文件),Fluent NHibernate 可

java基础--JDK安装、环境变量配置、工具开发第一个程序、数据类型、运算符

**-----Java基础大纲-----**   **-----本章节-----** 1.Java语言的历史.特点及工作原理 2.JRE和JDK的介绍 3.Java运行环境和开发工具 4.Java基础语法 **-----下一章节-----** 5.条件语句 6.循环 7.数组 ============================================== 一:历史及开发准备 1.Java发展历程及来源 (1)发展历程 1996年1月,Sun公司发布了Java的第一个开发工具包(JD

Linux下C++的编程——开发环境搭建与第一个程序

上一篇文章Linux下C++的编程--开偏介绍中我们已经介绍了GUN.GCC.G++等一些重要的概念,现在应该开始动手实践了! 开发工具的安装 环境 Distributions版本:CentOS 6.7 Linux内核片:2.6.32-573.3.1.el6.i686 一般Linux安装完之后默认就已经安装了GCC(GNU Compiler Collection),你可以查看一下gcc和g++的版本号检查gcc和g++是否已经安装. [luowf@luoweifu ~]$ gcc -v gcc

日更第2期-2015-1-15-openFrameworks系列第一讲-手把手制作openFrameworks上的第一个程序!

恩,今天和朋友打球来着,于是今天的案例程序就做一个球吧!O(∩_∩)O哈哈~ 首先,没有看过上一篇教程的同学,还有还没有下载好VS和OpenFrameworks的同学,都去下一下. 传送地址:http://www.cnblogs.com/linongbo/p/4227552.html 那么,开始今天的日更啦! Hello OpenFrameworks! VS的安装部分我就不说了,不过我个人建议——默认是安装在C盘的,不过你要是手动改到别的盘上的话,C盘上 依然会有6G左右的内容.......Σ(

Android使用AndEngine创建第一个程序

首先要把andengine.jar复制到libs文件夹里 01 package com.hu.anden; 02   03 import org.anddev.andengine.engine.Engine; 04 import org.anddev.andengine.engine.camera.Camera; 05 import org.anddev.andengine.engine.options.EngineOptions; 06 import org.anddev.andengine.

在Win7(64位)使用VS2015运行《OpenGL编程指南》第八版第一章程序的方法

前言:笔者第一次用vs2015来实现<OpenGL编程指南>第八版第一个程序时确实花费了不少时间,按照网上教程,尝试了各种方法,最终花费了两个上午加一个下午的时间, 成功运行了程序,花了这么多时间,确实让人懊恼,现在把运行程序的步骤记录下来,以便查阅. 1.第一步,下载oglpg-8th-edith. 如果去书本上的官网下载,下载的是第九版的,而不是第八版的源码. 去其他网站下载,下载的这个包里面没有第一章的源码,可以网上黏贴其他人的代码,建议下第八版源码,下载网址:链接:http://pan