Fluent Nhibernate(以下简称FN)发展到如今,已经相当成熟了,在Nhibernate的书中也相应的推荐了使用FN来进行映射配置,之前写的FN之旅至今还有很多人会来私信我问题,说来惭愧,从FN之旅四至今已经4年多,至今还未更新过此系列,原因有很多,最大的就是懒惰,哈。

安装

现在在项目中使用FN很方便,使用Nuget管理就可以了,但我还是建议大家,可以下载源代码,自己可以详细了解下。

当然,您也可以用命令台来进行安装。说个题外话,NuGet真心不错,至少已经做新项目的时候不用到处去整理lib包了,从NuGet进行下载、更新、卸载都很方便,而且还能自搭建自己公司的服务器,不过目前还是有些问题,有时候在下载最新包无法使用的情况下,无法自动降低版本,还得自己去手动控制台下载,非常不便。

在NuGet下载FluentNhibernate后,会自动下载安装Nhibernate及Iesi。

配置

准备工作完成,今天我们要说下FN的AutoMapping,之前呢我们都是用了FluentMapping进行手动的Map映射,如果可以的话,请大家还是使用之前的映射方式,因为AutoMapping有很多契约,您需要按照一定的规范编写您的对象。

我们先看下ISessionFactory中的Mapping配置:

    private static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2005
.ConnectionString(s => s.Server(".")
.Database("MyNHibernate")
.TrustedConnection()))
.Mappings(m => m.FluentMappings.Add<Store>())
.BuildSessionFactory();
}

这是我们手动映射,Mapping()中指定了用FluentMappings进行映射,我们只要把它改成AutoMapping:

    private static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2005
.ConnectionString(s => s.Server(".")
.Database("MyNHibernate")
.TrustedConnection()))
.Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Store>()))
.BuildSessionFactory();
}

红色字体为不同之处,Store是我们需要映射的实体类,可能您会用为何不能像FluentMapping一样Add<T>()呢?因为这里考虑到一些契约的问题,它的Add参数为AutoPersistenceModel类型,接下来会说的。

数据库结构

接下来,我们设计一个数据库结构,简单点:

员工,仓库,产品,对应关系也全部到位了

实体类代码

我们来编写对应的Model代码:

public class Store
{
public Store()
{
Products = new List<Product>();
} public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual IEnumerable<Product> Products { get; set; }
} public class UserName
{
public string FirstName { get; set; } public virtual string LastName { get; set; }
} public class Employee
{
public virtual int Id { get; set; } public virtual UserName Name { get; set; } public virtual Store Store { get; set; }
} public class Product
{
public Product()
{
Stores = new List<Store>();
} public virtual int Id { get; set; } public virtual float Price { get; set; } public virtual string Name { get; set; } public virtual IEnumerable<Store> Stores { get; set; }
}

好了,代码编写完毕,接下来是映射吗???No,无需映射了,因为我们用了AutoMapping,一切交给FN吧,我们接下来只要编写测试代码即可。

测试

我们先配置ISessionFactory:

     private static string dbfile = ConfigurationManager.AppSettings["dbfile"];
private static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(SQLiteConfiguration.Standard.UsingFile(dbfile))
.Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Store>()))
.ExposeConfiguration(BuildSchema) //利用Nhibernate的SchemaExport创建数据库及其架构
.BuildSessionFactory();
} private static void BuildSchema(NHibernate.Cfg.Configuration obj)
{
//delete the existing db on each run
if (File.Exists(dbfile))
File.Delete(dbfile); new SchemaExport(obj).Create(false, true);
}

在这里,我用了Sqlite做为我们的数据库,ORM最大的好处就是我们可以随意的变更我们的数据库类型,不需要考虑其类型,这是我选择Nhibernate的原因,EF虽然通过扩展能够支持其他数据库,但我相信用EF使用其他数据库的人很少吧。用ExposeConfiguration方法委托Nhibernate的SchemaExport来创建数据库架构,相信很多NH玩家都会用吧。不过不建议把它用在稍大的项目里,我们的项目数据库会随着项目需求的增加和改变会经常修改的,建议用专业的数据库管理,比如Migrator,有兴趣下次可以开篇介绍下,用下来还是不错的。

[Fact]
public void DemoTest()
{
using (var session = CreateSessionFactory().OpenSession())
{
new PersistenceSpecification<Employee>(session)
.CheckProperty(c => c.Id, 1)
.CheckProperty(c => c.Name.FirstName, "James")
.CheckProperty(c => c.Name.LastName, "YinG")
.CheckReference(c => c.Store, new Store() { Name = "MyStore" })
.VerifyTheMappings();
}
}

我们利用XUnit进行测试下,您会发现报错:

这是为什么呢?这个其实就是AutoMapping在处理映射的时候,都是按照一定的规则去映射的,细心的朋友可能发现,我们的索引字段的字段名都是Id,这就是AutoMapping的约定,我们也可以自己来进行配置。

刚我们的测试报错,是因为Employee中的Name是个UserName类,Nhibernate的Component,我在FN之旅四(上)中有介绍到,默认情况下映射根据字段映射到数据库的,所以上面的测试会报错,接下来我们自己配置下:

编写一个类,继承DefaultAutomappingConfiguration:

public class CustomConfiguration : DefaultAutomappingConfiguration
{
public override bool IsComponent(Type type)
{
return type == typeof(UserName);
}
}

重写IsComponent方法,简单吧,核对下类型即可,写完自己的规则后,我们需要在建立SessionFactory的时候引入此配置:

.Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Store>(new CustomConfiguration())))

现在您还无法测试通过,因为我用了PersistenceSpecification进行测试的,在进行常规的测试时是没有问题的,但遇到Component或者Reference之类的,都需要我们自己来写一个IEqualityComparer的实现:

public class UserNameComparer : IEqualityComparer
{
public new bool Equals(object x, object y)
{
var username_x = x as UserName;
if (username_x == null) return false;
var username_y = y as UserName;
if (username_y == null) return false; return username_x.FirstName.Equals(username_y.FirstName) &&
username_x.LastName.Equals(username_y.LastName);
} public int GetHashCode(object obj)
{
throw new NotImplementedException();
}
} public class StoreComparer : IEqualityComparer
{
public new bool Equals(object x, object y)
{
var Store_x = x as Store;
if (Store_x == null) return false;
var Store_y = y as Store;
if (Store_y == null) return false; return Store_x.Id == Store_y.Id;
} public int GetHashCode(object obj)
{
throw new NotImplementedException();
}
}

好,修改下我们的测试代码:

[Fact]
public void DemoTest()
{
using (var session = CreateSessionFactory().OpenSession())
{
new PersistenceSpecification<Employee>(session)
.CheckProperty(c => c.Id, 1)
.CheckProperty(c => c.UserName, new UserName{
FirstName = "James", LastName = "YinG"
}, new UserNameComparer())
.CheckReference(c => c.Store, new Store() { Name = "MyStore" }, new StoreComparer())
.VerifyTheMappings();
}
}

在进行下测试,这下我们通过了:

这里我只测试了Employee和Store两个实体,对于多对多还未测试,时间有限,等有时间下篇继续下。今天介绍了AutoMapping简单的介绍,但在使用中您要时刻注意,AutoMapping是有很多限制的,比如Id,比如Component等,当然我们可以通过重写DefaultAutomappingConfiguration的一些方法来进行合适的一些配置,如果您要对持久类有一些要求,不对一对多的LazyLoad或者Cascade之类的,您需要通过实现IReferenceConvention,IHasManyConvention,IHasManyToManyConvention进行配置,今天就不多讲了,下次吧。

Fluent Nhibernate确实是个好东西,让我在开发上省去了很多时间,今天虽然介绍了AutoMapping,但我不推荐您在您的项目中使用,用起来没手感(个人感觉),需要约定的东西太多了,对于数据库结构也得按照他的契约来,否则就得自己重写一些方法,实现一些类,有点累人。但在开发一些小工具时,又要用到小型存储数据的话,不妨可以试试这种方式。

PS:今天本来心情不错,没想到有客人来拉横幅,一直在公司吵闹,害的我无法集中精力,估计在文章中会有错的地方,大家见谅了。

Fluent Nhibernate之旅(五)--利用AutoMapping进行简单开发的更多相关文章

  1. Fluent NHibernate之旅

    Fluent NHibernate 之旅 导航篇: [原创]Fluent NHibernate之旅开篇: [原创]Fluent NHibernate之旅二--Entity Mapping: [原创]F ...

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

    英文原文地址:https://github.com/jagregory/fluent-nhibernate/wiki/Getting-started 翻译原文地址:http://www.cnblogs ...

  3. [Fluent NHibernate]一对多关系处理

    目录 写在前面 系列文章 一对多关系 总结 写在前面 上篇文章简单介绍了,Fluent Nhibernate使用代码的方式生成Nhibernate的配置文件,以及如何生成持久化类的映射文件.通过上篇的 ...

  4. Fluent NHibernate AutoMapping Conventions

    前言 使用nhibernate在项目中不管是代码或者xml文件映射方式,如果项目较大编写映射也应该算一笔大的工作量了,使用Fluent Nhibernate自己编写映射规则,将从conventions ...

  5. Fluent NHibernate and Spring.net

    http://blog.bennymichielsen.be/2009/01/04/using-fluent-nhibernate-in-spring-net/ http://comments.gma ...

  6. NHibernate之旅系列文章导航

    NHibernate之旅系列文章导航 宣传语 NHibernate.NHibernate教程.NHibernate入门.NHibernate下载.NHibernate教程中文版.NHibernate实 ...

  7. NHibernate之旅(18):初探代码生成工具使用

    本节内容 引入 代码生成工具 结语 引入 我们花了大量的篇幅介绍了相关NHibernate的知识.一直都是带着大家手动编写代码,首先创建数据库架构.然后编写持久化类和映射文件,最后编写数据操作方法.測 ...

  8. 全自动迁移数据库的实现 (Fluent NHibernate, Entity Framework Core)

    在开发涉及到数据库的程序时,常会遇到一开始设计的结构不能满足需求需要再添加新字段或新表的情况,这时就需要进行数据库迁移. 实现数据库迁移有很多种办法,从手动管理各个版本的ddl脚本,到实现自己的mig ...

  9. [Fluent NHibernate]第一个程序

    目录 写在前面 Fluent Nhibernate简介 基本配置 总结 写在前面 在耗时两月,NHibernate系列出炉这篇文章中,很多园友说了Fluent Nhibernate的东东,也激起我的兴 ...

随机推荐

  1. css限制单行文本输入,超出部分使用...替换

    在实际应用中,经常需要只显示一行文字,不允许文字换行破坏整体样式的情况.例如'商品的名称','简介'等等.但是由于显示器的宽度不一样,会出现后台所给文字内容,一行文本容纳不下的情况.溢出的文本如果使用 ...

  2. iOS 大文件断点下载

    iOS 在下载大文件的时候,可能会因为网络或者人为等原因,使得下载中断,那么如何能够进行断点下载呢? // resumeData的文件路径 #define XMGResumeDataFile [[NS ...

  3. android WebView介绍

    在Android手机中内置了一款高性能webkit内核浏览器,在SDK中封装成名为WebView的组件. WebView使用: (1)添加权限:AndroidManifest.xml中必须使用许可&q ...

  4. 一起来学习android自定义控件3——边缘凹凸的View

    前言 最近做项目的时候遇到一个卡劵的效果,由于自己觉得用图片来做的话可以会出现适配效果不好,再加上自己自定义view方面的知识比较薄弱,所以想试试用自定义View来实现.先看设计图效果 实现分析 上面 ...

  5. ASP.NET MVC3 Razor 调试与预加载

    目录(?)[-] 获取服务器信息 FormsAuthenticationSlidingExpiration 属性 MVC3预加载   在ASP.NET MVC3开发中,调试中怎么也是不可缺少的,那对于 ...

  6. iframe大小自适应

    前几天,舍友去某互联网公司面前端研发工程师.回来后,他就跟我们聊了下面试官给他出的题.其中,有一道题是“如何实现iframe高度的自适应?”.好吧,我承认,我听到iframe这个词的第一反应就是:这个 ...

  7. Build 2015 Beijing & Windows 10 China Geek Challenge

    6月5日,借着Build 2015在北京召开分会的东风,参加了这次由微软中国举办的Windows 10中国开发者极客挑战赛. 白天是Build 2015课程,学习了Windows 10最新的技术,包括 ...

  8. 使用eclipse开发Morphline的Java代码段

    背景:morphline是一个轻量级的etl工具.除了提供标准化的方法之外,还可以定制化的开发java片段.定制化的java片段会在加载时被作为一个独立的类编译,对源数据作处理. morphline关 ...

  9. PostgreSQL-psql

    打开查看元命令实际执行的sql的功能和关闭 yun=> \set ECHO_HIDDEN on yun=> \set ECHO_HIDDEN off psql中输入\?查看命令提示 资讯性 ...

  10. Windows下配置Squid反向代理服务器

    Squid是一款类Unix系统下非常流行的服务器软件,其最重要的功能就是在客户端和服务端之间建立缓存.因而Squid可以用作反向代理,部署多级缓存或者搭建CDN等,无论名称是什么,本质上都是一样的.目 ...