[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类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernate;
using FluentNHibernate;
namespace Wolfy.Data
{
/// <summary>
/// Nhibernate辅助类
/// </summary>
public class FluentNHibernateHelper
{
private static ISessionFactory _sessionFactory;
private static ISession _session;
private static object _objLock = new object();
private FluentNHibernateHelper()
{ }
/// <summary>
/// 创建ISessionFactory
/// </summary>
/// <returns></returns>
public static ISessionFactory GetSessionFactory()
{
if (_sessionFactory == null)
{
lock (_objLock)
{
if (_sessionFactory == null)
{
//配置ISessionFactory
_sessionFactory = FluentNHibernate.Cfg.Fluently.Configure()
//数据库配置
.Database(
//方言
FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2012
//连接字符串
.ConnectionString(
c => c.Server(".")
.Password("sa")
.Username("sa")
.Database("Shop")
.TrustedConnection()
)
//是否显示sql
.ShowSql()
)
//映射程序集
.Mappings(m => m.FluentMappings
.AddFromAssembly(System.Reflection.Assembly.Load("Wolfy.Domain"))
.ExportTo("c:\\"))
.BuildSessionFactory(); }
}
}
return _sessionFactory; }
/// <summary>
/// 重置Session
/// </summary>
/// <returns></returns>
public static ISession ResetSession()
{
if (_session.IsOpen)
_session.Close();
_session = _sessionFactory.OpenSession();
return _session;
}
/// <summary>
/// 打开ISession
/// </summary>
/// <returns></returns>
public static ISession GetSession()
{
GetSessionFactory();
if (_session == null)
{
lock (_objLock)
{
if (_session == null)
{
_session = _sessionFactory.OpenSession();
}
}
}
return _session;
} }
}
CreateSessionFactory方法对应Nhibernate的配置文件,通过代码的方式指定Nhibernate的配置信息,使用起来更方便。下面为之前学习Nhibernate时写的配置文件,不明白的可以回到NHIbernate系列文章去查看。
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
<session-factory>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string">
server=.;database=shop;uid=sa;pwd=sa
</property>
<property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
<mapping assembly="Wolfy.Shop.Domain"/>
</session-factory>
</hibernate-configuration>
一个例子
Customer持久化类
/// <summary>
/// 客户持久化类
/// </summary>
public class Customer
{
public virtual Guid CustomerID { set; get; }
public virtual int Version { set; get; }
public virtual string CustomerName { set; get; }
public virtual string CustomerAddress { set; get; }
}
添加映射类
CustomerMapping.cs
/// <summary>
/// Customer映射实体类,需要集成ClassMap泛型类
/// </summary>
public class CustomerMapping : ClassMap<Customer>
{
/// <summary>
/// 映射关系实体类的构造函数
/// 在构造函数中处理好映射关系
/// </summary>
public CustomerMapping()
{
//指定持久化类对应的数据表
Table("TB_Customer");
//自动增长的id
//Id(i => i.CustomerID);
//映射关系
Id<Guid>("CustomerID").GeneratedBy.Guid();
Map(m => m.CustomerAddress).Length().Nullable();
Map(m => m.CustomerName).Length().Nullable();
Map(m => m.Version);
}
}
映射配置类需继承ClassMap泛型类,在构造函数中可以通过Map方法,指定字段与数据表字段的对应关系,Map有两个重载方法,如下:
//
// 摘要:
// Create a property mapping.
//
// 参数:
// memberExpression:
// Property to map
public PropertyPart Map(Expression<Func<T, object>> memberExpression);
//
// 摘要:
// Create a property mapping.
//
// 参数:
// memberExpression:
// Property to map
//
// columnName:
// Property column name
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方法
/// <summary>
/// 客户类数据层
/// </summary>
public class CustomerData
{
/// <summary>
/// 添加客户对象
/// </summary>
/// <param name="customer"></param>
/// <returns></returns>
public bool AddCustomer(Customer customer)
{
ISession session = FluentNHibernateHelper.GetSession();
using (var trans = session.BeginTransaction())
{
try
{
session.SaveOrUpdate(customer);
session.Flush();
trans.Commit();
return true;
}
catch (Exception)
{
trans.Rollback();
return false;
}
} }
}
你会发现,方法与使用Nhibernate的时候的方法实现没什么区别,代码相同,唯一的区别就是配置文件的编写方式,一种是使用代码实现,一种是使用xml文件进行配置的。
单元测试
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Wolfy.Domain.Entities;
using Wolfy.Data;
namespace Wolfy.UnitTest
{
[TestClass]
public class CustomerDataTest
{
private CustomerData _customerData;
public CustomerDataTest()
{
_customerData = new CustomerData();
}
[TestMethod]
public void AddCustomerTest()
{
var result = _customerData.AddCustomer(
new TB_Customer()
{
Version = ,
CustomerName = "wolfy",
CustomerAddress = "中国 北京",
CustomerID = Guid.NewGuid()
}
);
Assert.IsTrue(result);
}
}
}
描述:通过数据层的AddCustomer方法向数据库中添加一个客户对象,并获得添加结果,断言结果为true,则测试通过。
运行测试,测试结果
生成的sql语句
exec sp_executesql N'INSERT INTO [TB_Customer]
(CustomerAddress, CustomerName, Version, CustomerID)
VALUES (@p0, @p1, @p2, @p3)',
N'@p0 nvarchar(4000),
@p1 nvarchar(4000),
@p2 int,
@p3 uniqueidentifier',
@p0=N'中国 北京',
@p1=N'wolfy',
@p2=1,
@p3='F15D04CF-300F-45C1-A774-3394CBA08155'
回头看一下,在FluentNhibernateHelper中,有这样一句代码:
//映射程序集
.Mappings(m => m.FluentMappings
.AddFromAssembly(System.Reflection.Assembly.Load("Wolfy.Domain"))
.ExportTo("c:\\"))
意思是将映射文件导出到c盘下,那么我们看一下c盘下生成了什么?
你会发现此时的xml文件正是Nhibernate中对应持久化类的映射文件,内容为:
<hibernate-mapping xmlns="urn:nhibernate-mapping-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">
<id type="System.Guid, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="CustomerID" />
<generator class="guid" />
</id>
<property name="CustomerAddress" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="CustomerAddress" length="50" not-null="false" />
</property>
<property name="CustomerName" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="CustomerName" length="32" not-null="false" />
</property>
<property name="Version" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Version" />
</property>
</class>
</hibernate-mapping>
总结
关于Fluent Nhibernate的基本使用就介绍到这里,不管怎样,先让第一个程序跑起来,才算是走好了第一步。
本篇内容学习了如何使用Fluent Nhibernate生成配置文件及映射文件。
参考文章
http://www.cnblogs.com/inday/archive/2009/08/04/Study-Fluent-NHibernate-Start.html
[Fluent NHibernate]第一个程序的更多相关文章
- [Fluent NHibernate]一对多关系处理
目录 写在前面 系列文章 一对多关系 总结 写在前面 上篇文章简单介绍了,Fluent Nhibernate使用代码的方式生成Nhibernate的配置文件,以及如何生成持久化类的映射文件.通过上篇的 ...
- Fluent NHibernate
Fluent NHibernate]第一个程序 目录 写在前面 Fluent Nhibernate简介 基本配置 总结 写在前面 在耗时两月,NHibernate系列出炉这篇文章中,很多园友说了Flu ...
- 全自动迁移数据库的实现 (Fluent NHibernate, Entity Framework Core)
在开发涉及到数据库的程序时,常会遇到一开始设计的结构不能满足需求需要再添加新字段或新表的情况,这时就需要进行数据库迁移. 实现数据库迁移有很多种办法,从手动管理各个版本的ddl脚本,到实现自己的mig ...
- 【翻译】Fluent NHibernate介绍和入门指南
英文原文地址:https://github.com/jagregory/fluent-nhibernate/wiki/Getting-started 翻译原文地址:http://www.cnblogs ...
- 【翻译】首个基于NHibernate的应用程序
首个基于NHibernate的应用程序 Your first NHibernate based application 英文原文地址:http://www.nhforge.org/wikis/how ...
- Fluent NHibernate and Spring.net
http://blog.bennymichielsen.be/2009/01/04/using-fluent-nhibernate-in-spring-net/ http://comments.gma ...
- fluent nhibernate 初体验
离开.net框架两年时间,发展的很快呀.原先自我感觉良好到以为只差一个MVP的考核什么的,现在觉得真的差好远了. 呵呵,废话就不多说了.这次花了两天时间才拿下fluent nhibernate的fir ...
- Fluent Nhibernate code frist简单配置
Fluent Nhibernate code frist简单配置 前言 在以前的项目开发过程中使用nhibernate做完orm映射工具需要编写大量的xml映射文件,项目过程中往往会因为一个字段等 ...
- Fluent NHibernate AutoMapping Conventions
前言 使用nhibernate在项目中不管是代码或者xml文件映射方式,如果项目较大编写映射也应该算一笔大的工作量了,使用Fluent Nhibernate自己编写映射规则,将从conventions ...
随机推荐
- linux中的权限对于文件和目录的重要性
对于文件 r 可以读取文件的实际内容 w 可以编辑文件的内容 x 文件可以被系统执行 对于目录 r 具有读取目录的结构列表,也就是说你可以用ls命令查看目录下的内容列表 w 可以建立新的文件,删除文件 ...
- 浅谈Linux中的信号处理机制(二)
首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号处理机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Lin ...
- CML相关
!!:执行上一条命令 !blah:执行最近的以 blah 开头的命令,如 !ls !blah:p:仅打印输出,而不执行 !$:上一条命令的最后一个参数,与 Alt + . 相同 !$:p:打印输出 ! ...
- VIM 常用命令
1.当vi打开时默认为命令模式,要转入输入模式,需要按a或者i键. 命令模式下: :wq 保存并且退出 :w 只保存不推出 :q 不保存退出 :q! 不保存强制退出 :wq! 保存并强制退 ...
- 利用epoll写一个"迷你"的网络事件库
epoll是linux下高性能的IO复用技术,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率.另一点原因就是获取 ...
- Apache、nginx配置的网站127.0.0.1可以正常访问,内外网的ip地址无法访问,谁的锅?
最近做开发,发现一个比较尴尬的问题.因为我是一个web开发者,经常要用到Apache或者nginx等服务器软件,经过我测试发现,只要我打开了adsafe,我便不能通过ip地址访问我本地的网站了,比如我 ...
- 【Windows】用信号量实现生产者-消费者模型
线程并发的生产者-消费者模型: 1.两个进程对同一个内存资源进行操作,一个是生产者,一个是消费者. 2.生产者往共享内存资源填充数据,如果区域满,则等待消费者消费数据. 3.消费者从共享内存资源取数据 ...
- java线程跟多线程
java创建线程两种方式: 1.继承Thread创建线程 /** * Created by lsf on 16/4/18. */ class NewThread extends Thread { Ne ...
- oracle基本操作符/运算符/操作语言
racle中的操作符算术操作符: 无论是在sqlserver,或者是java中,每种语言它都有算术操作符,大同小异.Oracle中算术操作符(+)(-)(*)(/) 值得注意的是:/ 在oracle中 ...
- 【笔记6】用pandas实现条目数据格式的推荐算法 (基于物品的协同)
''' 基于物品的协同推荐 矩阵数据 说明: 1.修正的余弦相似度是一种基于模型的协同过滤算法.我们前面提过,这种算法的优势之 一是扩展性好,对于大数据量而言,运算速度快.占用内存少. 2.用户的评价 ...