上篇文章详细讨论了FluentNHibernate的基本映射的使用方法,它的映射基本用法是跟NHibernate完全一样的,首先要创建数据库链接配置文件,然后编写Table的Mapping,最后编写Unit Test来测试模块Mapping是否成功执行。FluentNHibernate之所以替代NHibernate并不仅仅是因为对Mapping配置文件的优化,另外它换可以优化数据库的链接xml以及规避Mapping文件的编写,这种完全自动化的编程方法就是AutoMapping,FluentNHibernate封装了自动化映射的方法,使得开发人员只需要几种到对Table的修改中,而不需要考虑数据模型到对象模型的转化过程。
       在项目中如果使用了AutoMapping那么它的具体的架构图如下

上面的架构图使用了AutoMapping,它的使用能够避免繁杂的Mapping文件的编写,也就是说NHibernate在访问数据库时首先要从FluentNHibernate那里获取对象和数据是如何相互转化的,然后FluentNHibernate会从AutoMapping中获取各种映射的规则,也就是说AutoMapping只需要重写对象模型的映射规则就可以实现完全的映射,这样就使得程序的开发变得相当简单。

一、AutoMapping

上文使用架构图对FluentNHibernate的AutoMapping做了初步的解读,可以看出AutoMapping是依附于FluentNHibernate的,而且FluentNHibernate是依附于NHibernate的,它们三者首先是NHibernate先工作,查找到FluentNHibernate,然后是FluentNHibernate查找到AutoMapping的规则,按照规则进行映射。
       往往在开发时我们都会把Mapping和Models放到Core的程序集内,供其它层的程序集调用,如上图的Repository层,是对数据库做的一系列操作,都封装到该层中。

1.1 AutoMapping详解


在没有AutoMapping情况下如果使用FluentNHibernate来实现映射的话,首先要创建Mapping文件,然后对每个Entity都做Mapping代码的编写,但是这样就太麻烦了,因为如果有很多表的话一个个的编写Mapping很浪费时间,同时也会产生很多冗余的Code,所以这时候可以考虑使用AutoMapping来映射文件,只不过需要按照创建的规则来创建数据库的。
      (1)创建AutoMapping的映射配置类,继承DefaultAutomappingConfiguration类,并重写ShouldMap方法,指定实体类所在的命名空间
      (2)实现映射的接口,定义Entity到Table自动Mapping的规则,主要的接口如下:
            IClassConvention,Entity Class到Table的映射,需要实现指定Table名称的Apply方法,默认情况下是以Entity的名称作为Table名称。
            IIdConvention,Entity Class到Table ID的映射规则,需要实现指定Table ID生成的规则及ID的生成规则等,如果不实现该接口的话默认情况下会以“实体名_ID”形式命名Table的ID。
            IReferenceConvention,Entity Class到Table的外键列映射规则,需要实现Apply方法,来指定外键列名称的生成规则及连接对象的加载规则,默认情况下会以“外键对象_ID”形式命名外键列。
            IPropertyConvention,Entity Class属性到Table列名称的生成规则及加载规则,默认情况下会以属性名作为Table的列名。
            IHasOneConvention,Entity Class一对一映射的规则及列的生成规则,需要实现Apply方法指定外键列的命名规则,同时也可以规定外键对象的加载和操作方式,默认情况下会以“对象_ID”形式命名。
            IHasManyConvention,Entity Class一对多映射的规则及列的生成规则,需要实现Apply方法指定列的命名规则,同时也可以规定外键对象的加载和操作方式,默认情况下会以“对象_ID”形式命名。
            IHasManyToManyConvention,Entity Class多对多映射的规则及列的生成规则,需要实现Apply方法指定关联表及关联表中列的命名规则,默认情况下会以“对象_ID”形式命名列名,“对象To对象”形式命名表名。

(3)编写Unit Test运行AutoMapping的配置文件,生成NHibernate的映射xml,查看映射是否成功。

Note:AutoMapping的映射过程会生成一些冗余表或者冗余列,如在多对多的映射过程中因为对象的两端都有另外一端对象的引用,所以在生成表结构时会同时生成两个关联表,但是在数据时只会使用到一个关联表。所以如果不是必要的情况不要使用AutoMapping来映射表结构,在一些特别小型的项目中可以考虑使用AutoMapping,大型的项目建议手动创建映射文件,这样可以手动的控制。

1.2 实例详解


上文对AutoMapping的使用过程做了详细的讨论,接下来我们将会创建一个代码实例来讨论AutoMapping的具体使用方法。
        这里还以上文中的数据结构图为例来详细的讨论AutoMapping的使用方法,示例中使用的AutoMapping自动生成的数据库结构图如下:

上图是使用了AutoMapping来映射Entity后生成的数据库结构图,图中包括了一对一、一对多、多对多的关系,这些关系在生成的时候是按照1.1所说的映射规则实现的,具体的使用方法将会按照上文中所说的开发步骤来详细讨论。

1.2.1 创建AutoMapping的配置文件

在使用NHibernate做开发时首先要创建一个数据库的镜像Session,在使用FluentNHibernate也是如此,在使用时首先要创建一个数据库的Session对象,然后通过将对象转化为持久态来实现数据的操作。

AutoMapping的配置文件在创建Session时首先要创建AutoPersistenceModel对象,也就是将实体类所在的程序集/命名空间及Entity到Table的映射规则注册到     FluentNHibernate的AutoMapping中,具体的代码如下:

  1. /// <summary>
  2. /// 继承默认的AutoMapping配置类
  3. /// 重写ShouldMap方法指定映射Entity所在的命名空间
  4. /// </summary>
  5. public class StoreConfiguration : DefaultAutomappingConfiguration
  6. {
  7. public override bool ShouldMap(Type type)
  8. {
  9. return type.Namespace == "ClassLibrary1.mapping";
  10. }
  11. }
  12. /// <summary>
  13. /// 创建SessionFactory
  14. /// </summary>
  15. public class Build
  16. {
  17. private static AutoPersistenceModel CreateAutomappings()
  18. {
  19. //AutoMap.Assembly(Assembly.Load("ClassLibrary1"), new StoreConfiguration())
  20. //添加需要映射的程序集,在添加时可以使用默认的DefaultAutomappingConfiguration也可以继承该类重写ShouldMap方法来指定映射的命名空间
  21. return AutoMap
  22. .Assembly(Assembly.Load("ClassLibrary1"), new StoreConfiguration())
  23. //Conventions.Setup()方法是将映射的具体规则绑定到AutoMapping配置中,如下配置了:
  24. //DefualtTableNameConvertion默认表命名方式
  25. //DefaultPrimarykeyConvention默认主键命名方式
  26. //DefualtStringLengthConvertion默认的字符串长度
  27. //DefaultReferenceConvention默认的外键创建方法
  28. //DefaultHasManyConvention默认的一对多的创建方法
  29. //DefualtHasOneConvertion默认的一对一的创建方法
  30. //HasManyToManyConvention默认的多对多的创建方法
  31. .Conventions.Setup(con =>
  32. {
  33. con.Add<DefualtTableNameConvertion>();
  34. con.Add<DefaultPrimarykeyConvention>();
  35. con.Add<DefualtStringLengthConvertion>();
  36. con.Add<DefaultReferenceConvention>();
  37. con.Add<DefaultHasManyConvention>();
  38. con.Add<DefualtHasOneConvertion>();
  39. con.Add<HasManyToManyConvention>();
  40. });
  41. }
  42. public ISessionFactory CreateSessionFactory()
  43. {
  44. return Fluently
  45. .Configure()    //创建或者指定数据库的配置xml,这里使用的是自动创建的方法
  46. //指定数据库的映射方法,其实它的底层使用的是反射来实现的映射
  47. .Database(
  48. MsSqlConfiguration
  49. .MsSql2005
  50. .ConnectionString(
  51. "Data Source=.;Initial Catalog=Mapping;Integrated Security=true;Pooling=True;Min Pool Size=20;Max Pool Size=60")
  52. //指定连接字符串
  53. .ShowSql()
  54. )
  55. //配置映射规则
  56. .Mappings(m => m.AutoMappings.Add(CreateAutomappings()) //将创建的AutoPersistenceModel对象添加到AutoMapping中
  57. .ExportTo("c:\\path") //导出映射文件
  58. )
  59. //生成数据库架构
  60. //new SchemaExport(cfg).Create(true, false)创建配置文件。
  61. //这里的Create方法是创建的脚本文件的映射方法,
  62. //第一个参数bool script指定是否生成数据库脚本
  63. //第二个参数bool export指定每次生成的数据库的创建脚本是否执行
  64. .ExposeConfiguration(cfg => new SchemaExport(cfg).Create(true, false))
  65. .BuildSessionFactory();
  66. }
  67. }
  1. /// <summary>
  2. /// 继承默认的AutoMapping配置类
  3. /// 重写ShouldMap方法指定映射Entity所在的命名空间
  4. /// </summary>
  5. public class StoreConfiguration : DefaultAutomappingConfiguration
  6. {
  7. public override bool ShouldMap(Type type)
  8. {
  9. return type.Namespace == "ClassLibrary1.mapping";
  10. }
  11. }
  12.  
  13. /// <summary>
  14. /// 创建SessionFactory
  15. /// </summary>
  16. public class Build
  17. {
  18.  
  19. private static AutoPersistenceModel CreateAutomappings()
  20. {
  21. //AutoMap.Assembly(Assembly.Load("ClassLibrary1"), new StoreConfiguration())
  22. //添加需要映射的程序集,在添加时可以使用默认的DefaultAutomappingConfiguration也可以继承该类重写ShouldMap方法来指定映射的命名空间
  23. return AutoMap
  24. .Assembly(Assembly.Load("ClassLibrary1"), new StoreConfiguration())
  25. //Conventions.Setup()方法是将映射的具体规则绑定到AutoMapping配置中,如下配置了:
  26. //DefualtTableNameConvertion默认表命名方式
  27. //DefaultPrimarykeyConvention默认主键命名方式
  28. //DefualtStringLengthConvertion默认的字符串长度
  29. //DefaultReferenceConvention默认的外键创建方法
  30. //DefaultHasManyConvention默认的一对多的创建方法
  31. //DefualtHasOneConvertion默认的一对一的创建方法
  32. //HasManyToManyConvention默认的多对多的创建方法
  33. .Conventions.Setup(con =>
  34. {
  35. con.Add<DefualtTableNameConvertion>();
  36. con.Add<DefaultPrimarykeyConvention>();
  37. con.Add<DefualtStringLengthConvertion>();
  38. con.Add<DefaultReferenceConvention>();
  39. con.Add<DefaultHasManyConvention>();
  40. con.Add<DefualtHasOneConvertion>();
  41. con.Add<HasManyToManyConvention>();
  42. });
  43. }
  44.  
  45. public ISessionFactory CreateSessionFactory()
  46. {
  47. return Fluently
  48. .Configure() //创建或者指定数据库的配置xml,这里使用的是自动创建的方法
  49. //指定数据库的映射方法,其实它的底层使用的是反射来实现的映射
  50. .Database(
  51. MsSqlConfiguration
  52. .MsSql2005
  53. .ConnectionString(
  54. "Data Source=.;Initial Catalog=Mapping;Integrated Security=true;Pooling=True;Min Pool Size=20;Max Pool Size=60")
  55. //指定连接字符串
  56. .ShowSql()
  57. )
  58. //配置映射规则
  59. .Mappings(m => m.AutoMappings.Add(CreateAutomappings()) //将创建的AutoPersistenceModel对象添加到AutoMapping中
  60. .ExportTo("c:\\path") //导出映射文件
  61. )
  62. //生成数据库架构
  63. //new SchemaExport(cfg).Create(true, false)创建配置文件。
  64. //这里的Create方法是创建的脚本文件的映射方法,
  65. //第一个参数bool script指定是否生成数据库脚本
  66. //第二个参数bool export指定每次生成的数据库的创建脚本是否执行
  67. .ExposeConfiguration(cfg => new SchemaExport(cfg).Create(true, false))
  68. .BuildSessionFactory();
  69. }
  70.  
  71. }

有了上面的配置代码就可以实现AutoMapping规则了,但是往往我们的配置文件中需要实现映射的接口,通过实现这些接口来定义Entity和Table的相互映射的规则,实现这些接口后将这些类添加到SetUp到相应的AutoMapping中。

1.2.2 实现映射接口

添加好了AutoMapping的配置文件后基本上已经可以实现映射了,但是如果我们没有自定义映射规则的话将会以默认的方式生成相应的表结构,这些生成的表结构也可以通过实现接口来自定义这些规则,具体方法如下。

      (1)IClassConvention

         通过实现该接口来定义映射的Entity Class到Table的映射转换规则,如果不重写生成规则的话默认会以对象名作为表名。具体定义实现方法如下代码:

  1. public class DefualtTableNameConvertion : IClassConvention
  2. {
  3. /// <summary>
  4. /// 指定生成的表名或者表名到对象的映射
  5. /// </summary>
  6. /// <param name="instance">需要映射的Entity对象</param>
  7. public void Apply(FluentNHibernate.Conventions.Instances.IClassInstance instance)
  8. {
  9. //定义生成表名的规则,实体类名+s
  10. instance.Table(instance.EntityType.Name + "s");
  11. }
  12. }
  1. public class DefualtTableNameConvertion : IClassConvention
  2. {
  3. /// <summary>
  4. /// 指定生成的表名或者表名到对象的映射
  5. /// </summary>
  6. /// <param name="instance">需要映射的Entity对象</param>
  7. public void Apply(FluentNHibernate.Conventions.Instances.IClassInstance instance)
  8. {
  9. //定义生成表名的规则,实体类名+s
  10. instance.Table(instance.EntityType.Name + "s");
  11. }
  12. }

(2)IIdConvention

        实现该接口来定义映射的Entity Class中的属性列到Table ID的映射规则,同时也可以指定ID的规则,默认情况下会以“实体名_ID”形式命名Table的ID。

  1. public class DefaultPrimarykeyConvention : IIdConvention
  2. {
  3. /// <summary>
  4. /// 指定Entity Class到Table ID的生成规则,及ID的规则
  5. /// </summary>
  6. /// <param name="instance">生成实体的对象</param>
  7. public void Apply(FluentNHibernate.Conventions.Instances.IIdentityInstance instance)
  8. {
  9. instance.Column(instance.EntityType.Name + "ID");
  10. instance.GeneratedBy.Native();
  11. }
  12. }
  1. public class DefaultPrimarykeyConvention : IIdConvention
  2. {
  3. /// <summary>
  4. /// 指定Entity Class到Table ID的生成规则,及ID的规则
  5. /// </summary>
  6. /// <param name="instance">生成实体的对象</param>
  7. public void Apply(FluentNHibernate.Conventions.Instances.IIdentityInstance instance)
  8. {
  9. instance.Column(instance.EntityType.Name + "ID");
  10. instance.GeneratedBy.Native();
  11. }
  12. }

(3)IReferenceConvention

        实现该接口指定Entity Class到Table的外键列映射规则,默认情况下会以“外键对象_ID”形式命名外键列。

  1. public class DefaultReferenceConvention : IReferenceConvention
  2. {
  3. /// <summary>
  4. /// 指定对象外键的生成规则
  5. /// </summary>
  6. /// <param name="instance">外键对象</param>
  7. public void Apply(IManyToOneInstance instance)
  8. {
  9. instance.Column(instance.Name + "ID");
  10. instance.LazyLoad();
  11. }
  12. }
  1. public class DefaultReferenceConvention : IReferenceConvention
  2. {
  3. /// <summary>
  4. /// 指定对象外键的生成规则
  5. /// </summary>
  6. /// <param name="instance">外键对象</param>
  7. public void Apply(IManyToOneInstance instance)
  8. {
  9. instance.Column(instance.Name + "ID");
  10. instance.LazyLoad();
  11.  
  12. }
  13. }

(4)IPropertyConvention

       Entity Class属性到Table列名称的生成规则及加载规则,同时也可以定义数据库列类型的生成的规则,默认情况下会以属性名作为Table的列名。

  1. public class DefualtStringLengthConvertion : IPropertyConvention
  2. {
  3. /// <summary>
  4. /// 配置Table列的名称及类型
  5. /// </summary>
  6. /// <param name="instance">对象的属性</param>
  7. public void Apply(FluentNHibernate.Conventions.Instances.IPropertyInstance instance)
  8. {
  9. //设置列的字符串长度为50
  10. instance.Length(50);
  11. }
  12. }
  1. public class DefualtStringLengthConvertion : IPropertyConvention
  2. {
  3. /// <summary>
  4. /// 配置Table列的名称及类型
  5. /// </summary>
  6. /// <param name="instance">对象的属性</param>
  7. public void Apply(FluentNHibernate.Conventions.Instances.IPropertyInstance instance)
  8. {
  9. //设置列的字符串长度为50
  10. instance.Length(50);
  11. }
  12. }

(5)IHasOneConvention

        Entity Class一对一映射的规则及列的生成规则,同时也可以规定外键对象的加载和操作方式,默认情况下会以“对象_ID”形式命名。

  1. public class DefualtHasOneConvertion : IHasOneConvention
  2. {
  3. /// <summary>
  4. /// 一对一映射中的外键列及对从表的操作的类型
  5. /// </summary>
  6. /// <param name="instance">关系对象</param>
  7. public void Apply(IOneToOneInstance instance)
  8. {
  9. //指定外键列的列名规则
  10. instance.ForeignKey(instance.EntityType.Name + "ID");
  11. //指定主表对从表的操作
  12. instance.Cascade.SaveUpdate();
  13. instance.LazyLoad();
  14. }
  15. }
  1. public class DefualtHasOneConvertion : IHasOneConvention
  2. {
  3. /// <summary>
  4. /// 一对一映射中的外键列及对从表的操作的类型
  5. /// </summary>
  6. /// <param name="instance">关系对象</param>
  7. public void Apply(IOneToOneInstance instance)
  8. {
  9. //指定外键列的列名规则
  10. instance.ForeignKey(instance.EntityType.Name + "ID");
  11. //指定主表对从表的操作
  12. instance.Cascade.SaveUpdate();
  13. instance.LazyLoad();
  14. }
  15. }

(6)IHasManyConvention

        Entity Class一对多映射的规则及列的生成规则,同时也可以规定外键对象的加载和操作方式,默认情况下会以“对象_ID”形式命名。

  1. public class DefaultHasManyConvention : IHasManyConvention
  2. {
  3. /// <summary>
  4. /// 一对多对象的生成规则
  5. /// </summary>
  6. /// <param name="instance"></param>
  7. public void Apply(IOneToManyCollectionInstance instance)
  8. {
  9. instance.Key.Column(instance.EntityType.Name + "ID");
  10. instance.Cascade.AllDeleteOrphan();
  11. instance.LazyLoad();
  12. }
  13. }
  1. public class DefaultHasManyConvention : IHasManyConvention
  2. {
  3. /// <summary>
  4. /// 一对多对象的生成规则
  5. /// </summary>
  6. /// <param name="instance"></param>
  7. public void Apply(IOneToManyCollectionInstance instance)
  8. {
  9. instance.Key.Column(instance.EntityType.Name + "ID");
  10. instance.Cascade.AllDeleteOrphan();
  11. instance.LazyLoad();
  12. }
  13. }

(7)IHasManyToManyConvention

        Entity Class多对多映射的规则及列的生成规则,默认情况下会以“对象_ID”形式命名列名,“对象To对象”形式命名表名。

  1. public class HasManyToManyConvention : IHasManyToManyConvention
  2. {
  3. /// <summary>
  4. /// 多对多映射的规则
  5. /// </summary>
  6. /// <param name="instance">多对多关系实例</param>
  7. public void Apply(IManyToManyCollectionInstance instance)
  8. {
  9. //指定表名的生成规则,将表名按字符排序较小的一方表名在前方,表名较大的放到后面
  10. instance.Table(instance.EntityType.Name.ToString()+instance.ChildType.Name.ToString());
  11. //关联列的一方的命名方式
  12. instance.Key.Column(instance.EntityType.Name.ToString()+"ID");
  13. //关系列的另一方的命名方式
  14. instance.Relationship.Column(instance.ChildType.Name.ToString()+"ID");
  15. }
  16. }
  1. public class HasManyToManyConvention : IHasManyToManyConvention
  2. {
  3. /// <summary>
  4. /// 多对多映射的规则
  5. /// </summary>
  6. /// <param name="instance">多对多关系实例</param>
  7. public void Apply(IManyToManyCollectionInstance instance)
  8. {
  9. //指定表名的生成规则,将表名按字符排序较小的一方表名在前方,表名较大的放到后面
  10. instance.Table(instance.EntityType.Name.ToString()+instance.ChildType.Name.ToString());
  11. //关联列的一方的命名方式
  12. instance.Key.Column(instance.EntityType.Name.ToString()+"ID");
  13. //关系列的另一方的命名方式
  14. instance.Relationship.Column(instance.ChildType.Name.ToString()+"ID");
  15. }
  16. }

1.2.3 编写Unit Test测试映射

上文对AutoMapping的映射规则做了详细的讨论,并且添加了映射中的AutoMapping的映射规则的代码,映射的规则其实相当的简单只需要实现相应的映射规则即可,如果不重写映射规则的话将会按照默认的方式生成数据库表结构,所以在创建表结构的时候需要按照一定的规则创建表结构,然后按照自己创建的表结构的规则创建相应的映射规则配置文件,如上文的代码,接下来我们编写Unit Test来测试AutoMapping。



        规则创建完成后需要首先运行一次AutoMapping文件,将配置文件设置为如下代码:

  1. public ISessionFactory CreateSessionFactory()
  2. {
  3. return Fluently
  4. .Configure()    //创建或者指定数据库的配置xml,这里使用的是自动创建的方法
  5. //指定数据库的映射方法,其实它的底层使用的是反射来实现的映射
  6. .Database(
  7. MsSqlConfiguration
  8. .MsSql2005
  9. .ConnectionString(
  10. "Data Source=.;Initial Catalog=Mapping;Integrated Security=true;Pooling=True;Min Pool Size=20;Max Pool Size=60")
  11. //指定连接字符串
  12. .ShowSql()
  13. )
  14. //配置映射规则
  15. .Mappings(m => m.AutoMappings.Add(CreateAutomappings()) //将创建的AutoPersistenceModel对象添加到AutoMapping中
  16. .ExportTo("c:\\path") //导出映射文件
  17. )
  18. //生成数据库架构
  19. //new SchemaExport(cfg).Create(true, false)创建配置文件。
  20. //这里的Create方法是创建的脚本文件的映射方法,
  21. //第一个参数bool script指定是否生成数据库脚本
  22. //第二个参数bool export指定每次生成的数据库的创建脚本是否执行
  23. .ExposeConfiguration(cfg => new SchemaExport(cfg).Create(true, true))
  24. .BuildSessionFactory();
  25. }
  1. public ISessionFactory CreateSessionFactory()
  2. {
  3. return Fluently
  4. .Configure() //创建或者指定数据库的配置xml,这里使用的是自动创建的方法
  5. //指定数据库的映射方法,其实它的底层使用的是反射来实现的映射
  6. .Database(
  7. MsSqlConfiguration
  8. .MsSql2005
  9. .ConnectionString(
  10. "Data Source=.;Initial Catalog=Mapping;Integrated Security=true;Pooling=True;Min Pool Size=20;Max Pool Size=60")
  11. //指定连接字符串
  12. .ShowSql()
  13. )
  14. //配置映射规则
  15. .Mappings(m => m.AutoMappings.Add(CreateAutomappings()) //将创建的AutoPersistenceModel对象添加到AutoMapping中
  16. .ExportTo("c:\\path") //导出映射文件
  17. )
  18. //生成数据库架构
  19. //new SchemaExport(cfg).Create(true, false)创建配置文件。
  20. //这里的Create方法是创建的脚本文件的映射方法,
  21. //第一个参数bool script指定是否生成数据库脚本
  22. //第二个参数bool export指定每次生成的数据库的创建脚本是否执行
  23. .ExposeConfiguration(cfg => new SchemaExport(cfg).Create(true, true))
  24. .BuildSessionFactory();
  25. }

这样每次运行时都会检索数据库的表结构并创建相应的数据库表结构,所以在运行一次后要改为.ExposeConfiguration(cfg => new SchemaExport(cfg).Create(true, false))。

          使用单元测试方法来测试一对一的映射如下:

  1. [TestFixture]
  2. public class UnitTest1 : Build
  3. {
  4. [Test]
  5. public void TestUsers_UserDetails()
  6. {
  7. ISessionFactory sessionFactory = CreateSessionFactory();
  8. ISession Session = sessionFactory.OpenSession();
  9. //get user from database
  10. //User user1 = Session.Load<User>(2);
  11. //save the User data
  12. Session.Transaction.Begin();
  13. //User usreUser = Session.Get<User>(2);
  14. User user = new User()
  15. {
  16. Name = "Jack",
  17. No = "12321"
  18. };
  19. UserDetail userDetails = new UserDetail()
  20. {
  21. Age = 12,
  22. BirthDate = DateTime.Now.Date,
  23. Height = 240,
  24. Sex = 1
  25. };
  26. user.UserDetails = userDetails;
  27. userDetails.User = user;
  28. Session.Save(user);
  29. Session.Save(userDetails);
  30. Session.Transaction.Commit();
  31. }
  32. }
  1. [TestFixture]
  2. public class UnitTest1 : Build
  3. {
  4. [Test]
  5. public void TestUsers_UserDetails()
  6. {
  7. ISessionFactory sessionFactory = CreateSessionFactory();
  8. ISession Session = sessionFactory.OpenSession();
  9. //get user from database
  10. //User user1 = Session.Load<User>(2);
  11.  
  12. //save the User data
  13. Session.Transaction.Begin();
  14.  
  15. //User usreUser = Session.Get<User>(2);
  16. User user = new User()
  17. {
  18. Name = "Jack",
  19. No = "12321"
  20. };
  21. UserDetail userDetails = new UserDetail()
  22. {
  23. Age = 12,
  24. BirthDate = DateTime.Now.Date,
  25. Height = 240,
  26. Sex = 1
  27. };
  28. user.UserDetails = userDetails;
  29. userDetails.User = user;
  30. Session.Save(user);
  31. Session.Save(userDetails);
  32. Session.Transaction.Commit();
  33. }
  34. }

运行该Unit Test Method后生成的数据库表如下图:





运行完后插入的表结构的数据如下图:







编写代码测试多对多的映射关系如下:

  1. [TestFixture]
  2. public class UnitTest1:Build
  3. {
  4. [Test]
  5. public void TestUsers_UserDetails()
  6. {
  7. ISessionFactory sessionFactory = CreateSessionFactory();
  8. ISession Session=sessionFactory.OpenSession();
  9. //get user from database
  10. //User user1 = Session.Load<User>(2);
  11. //save the User data
  12. Session.Transaction.Begin();
  13. //User usreUser = Session.Get<User>(2);
  14. User user=new User()
  15. {
  16. Name = "Jack",
  17. No = "12321"
  18. };
  19. UserDetail userDetails=new UserDetail()
  20. {
  21. Age = 12,
  22. BirthDate = DateTime.Now.Date,
  23. Height = 240,
  24. Sex = 1
  25. };
  26. user.UserDetails = userDetails;
  27. userDetails.User = user;
  28. Session.Save(user);
  29. Session.Save(userDetails);
  30. Session.Transaction.Commit();
  31. }
  32. [Test]
  33. public void TestUsers_ProductProject()
  34. {
  35. ISessionFactory sessionFactory = CreateSessionFactory();
  36. ISession Session = sessionFactory.OpenSession();
  37. //get user from database
  38. //User user1 = Session.Load<User>(1);
  39. //save the User data
  40. Session.Transaction.Begin();
  41. Project project = new Project()
  42. {
  43. Name = "project1"
  44. };
  45. Product product1 = new Product()
  46. {
  47. Name = "Product1",
  48. Color = "Red",
  49. };
  50. Product product2 = new Product()
  51. {
  52. Name = "Product2",
  53. Color = "Red"
  54. };
  55. product1.Project.Add(project);
  56. product2.Project.Add(project);
  57. //Project project1 = new Project()
  58. //{
  59. //    Name = "project2"
  60. //};
  61. project.Product.Add(product1);
  62. project.Product.Add(product2);
  63. Session.Save(project);
  64. Session.Save(product1);
  65. Session.Save(product2);
  66. Session.Transaction.Commit();
  67. }
  68. [Test]
  69. public void TestUsers_ProjectProduct()
  70. {
  71. ISessionFactory sessionFactory = CreateSessionFactory();
  72. ISession Session = sessionFactory.OpenSession();
  73. //get user from database
  74. //User user1 = Session.Load<User>(1);
  75. //save the User data
  76. Session.Transaction.Begin();
  77. Project project = new Project()
  78. {
  79. Name = "project1"
  80. };
  81. Project project1 = new Project()
  82. {
  83. Name = "project2"
  84. };
  85. Product product = new Product()
  86. {
  87. Name = "Product1",
  88. Color = "Red",
  89. };
  90. product.Project.Add(project);
  91. product.Project.Add(project1);
  92. //project.Product.Add(product);
  93. //project1.Product.Add(product);
  94. Session.Save(project);
  95. Session.Save(project1);
  96. Session.Save(product);
  97. Session.Transaction.Commit();
  98. }
  99. }
  1. [TestFixture]
  2. public class UnitTest1:Build
  3. {
  4. [Test]
  5. public void TestUsers_UserDetails()
  6. {
  7. ISessionFactory sessionFactory = CreateSessionFactory();
  8. ISession Session=sessionFactory.OpenSession();
  9. //get user from database
  10. //User user1 = Session.Load<User>(2);
  11.  
  12. //save the User data
  13. Session.Transaction.Begin();
  14.  
  15. //User usreUser = Session.Get<User>(2);
  16. User user=new User()
  17. {
  18. Name = "Jack",
  19. No = "12321"
  20. };
  21. UserDetail userDetails=new UserDetail()
  22. {
  23. Age = 12,
  24. BirthDate = DateTime.Now.Date,
  25. Height = 240,
  26. Sex = 1
  27. };
  28. user.UserDetails = userDetails;
  29. userDetails.User = user;
  30. Session.Save(user);
  31. Session.Save(userDetails);
  32. Session.Transaction.Commit();
  33. }
  34.  
  35. [Test]
  36. public void TestUsers_ProductProject()
  37. {
  38. ISessionFactory sessionFactory = CreateSessionFactory();
  39. ISession Session = sessionFactory.OpenSession();
  40. //get user from database
  41. //User user1 = Session.Load<User>(1);
  42.  
  43. //save the User data
  44. Session.Transaction.Begin();
  45. Project project = new Project()
  46. {
  47. Name = "project1"
  48. };
  49. Product product1 = new Product()
  50. {
  51. Name = "Product1",
  52. Color = "Red",
  53. };
  54. Product product2 = new Product()
  55. {
  56. Name = "Product2",
  57. Color = "Red"
  58. };
  59. product1.Project.Add(project);
  60. product2.Project.Add(project);
  61. //Project project1 = new Project()
  62. //{
  63. // Name = "project2"
  64. //};
  65. project.Product.Add(product1);
  66. project.Product.Add(product2);
  67. Session.Save(project);
  68. Session.Save(product1);
  69. Session.Save(product2);
  70. Session.Transaction.Commit();
  71. }
  72. [Test]
  73. public void TestUsers_ProjectProduct()
  74. {
  75. ISessionFactory sessionFactory = CreateSessionFactory();
  76. ISession Session = sessionFactory.OpenSession();
  77. //get user from database
  78. //User user1 = Session.Load<User>(1);
  79.  
  80. //save the User data
  81. Session.Transaction.Begin();
  82. Project project = new Project()
  83. {
  84. Name = "project1"
  85. };
  86. Project project1 = new Project()
  87. {
  88. Name = "project2"
  89. };
  90. Product product = new Product()
  91. {
  92. Name = "Product1",
  93. Color = "Red",
  94. };
  95. product.Project.Add(project);
  96. product.Project.Add(project1);
  97. //project.Product.Add(product);
  98. //project1.Product.Add(product);
  99.  
  100. Session.Save(project);
  101. Session.Save(project1);
  102. Session.Save(product);
  103. Session.Transaction.Commit();
  104. }
  105. }

运行两个方法后查看生成的相应数据如下:

结语

本文详细讨论了AutoMapping的使用方法,主要讨论了AutoMapping的使用步骤并使用上篇文章中的数据库结构作为实例来演示了AutoMapping代码的实现过程,该Project的源码下载地址为:http://download.csdn.net/detail/zhang_xinxiu/8309201

         虽然使用AutoMapping来实现映射很简单,而且也能够减少代码的冗余,但是在大型项目中并不推荐使用此种方法来映射,因为AutoMapping有太多的不确定性,不够成熟,供查询的资料很少,为了避免风险建议使用FluentNHibernate来映射项目。

版权声明:本文为博主原创文章,未经博主允许不得转载。

【ORM】--FluentNHibernate之AutoMapping详解的更多相关文章

  1. Python:轻量级 ORM 框架 peewee 用法详解(二)——增删改查

    说明:peewee 中有很多方法是延时执行的,需要调用 execute() 方法使其执行.下文中不再特意说明这个问题,大家看代码. 本文中代码样例所使用的 Person 模型如下: class Per ...

  2. 【ORM】--FluentNHibernate之基本映射详解

           最近在做项目的时候用到了NHibernate,使用它并不困难,但是很麻烦.如果我的数据库有几百张表如果想要一个个的映射岂不是很麻烦,所以这种情况下使用NHibernate就会很笨重,虽然 ...

  3. .NET ORM框架 SqlSuagr4.0 功能详解与实践【开源】

    SqlSugar 4.0 ORM框架的优势 为了未来能够更好的支持多库分布式的存储,并行计算等功能,将SqlSugar3.x全部重写,现有的架构可以轻松扩展多库. 源码下载: https://gith ...

  4. python/ORM操作详解

    一.python/ORM操作详解 ===================增==================== models.UserInfo.objects.create(title='alex ...

  5. 2018.10.7 理解Hibernate的工作原理及其中的ORM详解

    复习 hibernate框架 简介j及其搭建: hibernate是一个开源框架,它是对象关联关系映射的框架,它对JDBC做了轻量级的封装,而我们java程序员可以使用面向对象的思想来操纵数据库. 1 ...

  6. Django框架 之 ORM查询操作详解

    Django框架 之 ORM查询操作详解 浏览目录 一般操作 ForeignKey操作 ManyToManyField 聚合查询 分组查询 F查询和Q查询 事务 Django终端打印SQL语句 在Py ...

  7. django ORM 外键详解

    Django中的外键: 首先,为了方便理解,我们把使用ForeignKey的字段所在的表定义为从表,把ForeignKey中to参数连接的表称为主表. 外键使用的先决条件: 在mysql数据表中,数据 ...

  8. ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借

    ASP.NET MVC深入浅出系列(持续更新)   一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...

  9. ORM详解

    讲解对象:ORM详解 作者:融水公子 rsgz 1 前言:开发流程正常只有简单的几步 0.1 配置数据库 0.2 定义模型 0.3 迁移文件 0.4 执行迁移生成数据表 0.5 使用模型类增删改查 2 ...

随机推荐

  1. osx下配置Cocos2d-x 3.x Android开发环境

    配置前需要准备的 首先需要看一下官网文档 http://www.cocos.com/doc/article/index?type=cocos2d-x&url=/doc/cocos-docs-m ...

  2. SSH基于Hibernate eventListener 事件侦听器的操作日志自动保存到数据库

    在spring xml配置文件中添加配置,包含:model.listener 在model中增加需要写入数据库对应表的model 在auditLog.xml配置文件中配置自己项目中,需要进行日志记录的 ...

  3. 转-Spring Framework中的AOP之around通知

    Spring Framework中的AOP之around通知 http://blog.csdn.net/xiaoliang_xie/article/details/7049183 标签: spring ...

  4. 可以链接不同源的资源的html元素(能实现跨域)

    可以链接不同源的资源的html元素(能实现跨域): img.script.css.video.audio.object.embed.applet.@font-face.frame.iframe等. ( ...

  5. CentOS 6、7下pptp vpn一键安装脚本

    之前有折腾过<CentOS 6.7下IPSEC/L2TP VPN一键安装脚本>,不稳定.不支持IOS,因此换成pptp,并已经添加到<lnmp一键安装包>.这个脚本可以单独使用 ...

  6. sql server远程备份和恢复

    sql server远程备份和恢复 SQLSERVER服务实例名称:192.168.0.2需要备份的数据库名称: a备份机器名称(Client端):192.168.0.3备份机用户:zf 密码:123 ...

  7. 服务 在初始化安装时发生异常:System.IO.FileNotFoundException: "file:///D:\testService"未能加载文件或程序集。系统找不到指定文件。

    @echo.@if exist "%windir%\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe" goto INSTALL ...

  8. Python字符串处理

    字符串输入: my_string = raw_input("please input a word:") 字符串判断: (1) 判断是不是纯字母 my_string.isalpha ...

  9. C# HmacMD5 加密

    string HmacMD5(string source, string key) { HMACMD5 hmacmd = new HMACMD5(Encoding.Default.GetBytes(k ...

  10. MySQL连接查询的简单概括+思维导图