NHibernate初学者指南(6):映射模型到数据库之方式二

使用Fluent NHibernate自动映射

使用Fluent NHibernate自动映射,首先要将映射的实体放到一个命名空间中,这使得通知AutoMapper哪些实体和值对象包含在映射中更容易。建议在你的项目中创建一个Domain文件夹,将需要映射的实体和值对象放到这个文件夹中。

因为隐式映射实体和值对象,需要为AutoMapping定义约定和例外。我们通过实现一个继承自DefaultAutomappingConfiguration的配置类实现。

假设我们已经将所有的实体和值对象放在了相同的命名空间中,这个命名空间只包含domain类,我们就可以如下面的代码定义配置类:

public class OrderingSystemConfiguration : DefaultAutomappingConfiguration
{
    public override bool ShouldMap(Type type)
    {
        return type.Namespace == typeof(Customer).Namespace;
    }
}

上面的代码告诉AutoMapping只映射那些和Customer实体有相同命名空间的类。

在AutoMapper工作之前,我们还需要告诉它更多的事情。我们必须告诉它在系统中谁是值对象。这可以在配置类中重写IsComponent方法实现,如下面代码所示:

public override bool IsComponent(Type type)
{
    var componentTypes = new[] { typeof(Name), typeof(Address) };
    return componentTypes.Contains(type);
}

配置系统使用自动映射,我们利用下面的代码:

var cfg = new OrderingSystemConfiguration();
var configuration = Fluently.Configure()
                    .Database(/* database config */)
                    .Mappings(m =>m.AutoMappings.Add(
                    AutoMap.AssemblyOf<Employee>(cfg)))
                    .BuildConfiguration();

 

实战时间–使用自动映射

在这个例子中,我们想定义一个基本的领域模型,使用Fluent NHibernate提供的自动映射来映射我们的模型,然后让NHibernate根据映射为我们生成数据库架构:

1. 在VS中创建一个Console Application,名字为:AutoMappingSample。

2. 添加NHibernate.dll和FluentNHibernate两个程序集到项目中。

3. 在项目中新建一个Domain文件夹。

4. 分别添加以下类到Domain文件夹中:

Customer类

namespace AutoMappingSample.Domain
{
    public class Customer
    {
        public virtual int Id { get; set; }
        public virtual string CustomerName { get; set; }
    }
}

LineItem类

namespace AutoMappingSample.Domain
{
    public class LineItem
    {
        public virtual int  Id { get; set; }
        public virtual int  Quantity { get; set; }
        public virtual decimal UnitPrice { get; set; }
        public virtual string ProductCode { get; set; }
    }
}

Order类

namespace AutoMappingSample.Domain
{
    public class Order
    {
        public virtual int Id { get; set; }
        public virtual DateTime OrderDate { get; set; }
        public virtual Customer Customer { get; set; }
        public virtual IList<LineItem> LineItems { get; set; }
    }
}

5. 在项目中添加一个OrderingSystemConfiguration类,继承自DefaultAutomappingConfiguration。

6. 重写ShouldMap方法,如下面的代码:

namespace AutoMappingSample
{
    public class OrderingSystemConfiguration : DefaultAutomappingConfiguration
    {
        public override bool ShouldMap(Type type)
        {
            return type.Namespace == typeof(Customer).Namespace;
        }
    }
}

7. 在Program类中添加如下using语句:

using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using FluentNHibernate.Automapping;
using AutoMappingSample.Domain;
using NHibernate.Tool.hbm2ddl;

8. 添加下面的代码到Program类的Main方法创建NHibernate配置。配置对象使用Fluent NHibernate的配置API创建用于自动映射。

var cfg = new OrderingSystemConfiguration();
var configuration = Fluently.Configure().Database(MsSqlConfiguration.MsSql2008)
                    .Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Customer>(cfg))).BuildConfiguration();

注意为这个操作定义数据库字符串没有必要,因为我们不访问数据库,只是告诉NHibernate哪种类型的数据库。

9. 添加下面的代码创建并在控制台上显示SQL脚本:

var exporter = new SchemaExport(configuration);
exporter.Execute(true, false, false);

10. 添加下面的代码避免程序不经确认就退出:

Console.WriteLine("按回车退出:");
Console.ReadLine();

11. 运行程序,控制台输出如下:

automapping

使用ConfORM自动映射

ConfORM是NHibernate contributions的一部分,可从http://code.google.com/p/codeconform/downloads/list下载。确保下载的版本兼容你使用的NHibernate版本。

和Fluent NHibernate的AutoMapper一样,ConfORM使用约定隐式定义领域模型的映射。这些约定可以重写,也可以定义我们自己的约定。

实战时间–使用ConfORM映射模型

在这个例子中,我们再一次创建一个简单的领域模型并使用ConfORM为我们创建一个隐式的映射。然后我们使用NHiernate的schema exporter创建SQL脚本来创建兼容我们模型的数据库架构。

1. 打开VS,创建一个Console Application项目,名字为:ConfORMSample。

2. 添加对NHibernate.dll和ConfORM.dll程序集的引用到项目中。我使用的NHibernate版本是3.1的,所以ConfORM也是兼容3.1的ConfORM 1.0.1.5。

3. 在项目中创建一个Domain文件夹。

4. 添加上一个例子中的Customer,Order和LineItem类到Domain文件夹。

Customer类

namespace ConfORMSample.Domain
{
    public class Customer
    {
        public virtual int Id { get; set; }
        public virtual string CustomerName { get; set; }
    }
}

Order类

namespace ConfORMSample.Domain
{
    public class Order
    {
        public virtual int Id { get; set; }
        public virtual DateTime OrderDate { get; set; }
        public virtual Customer Customer { get; set; }
        public virtual IList<LineItem> LineItems { get; set; }
    }
}

LineItem类

namespace ConfORMSample.Domain
{
    public class LineItem
    {
        public virtual int  Id { get; set; }
        public virtual int  Quantity { get; set; }
        public virtual decimal UnitPrice { get; set; }
        public virtual string ProductCode { get; set; }
    }
}

5. 在Program类中添加如下using语句:

using ConfORMSample.Domain;
using ConfOrm;
using ConfOrm.NH;
using NHibernate.Cfg;
using NHibernate.Cfg.Loquacious;
using NHibernate.Dialect;
using NHibernate.Driver;
using NHibernate.Tool.hbm2ddl;

6. 在Program类的Main方法中,使用NHibernate提供的fluent配置API创建一个NHibernate配置对象:

var configuration = new Configuration();
configuration.DataBaseIntegration(db =>
{
    db.Dialect<MsSql2008Dialect>();
    db.Driver<SqlClientDriver>();
});

7. 添加如下代码,确定要映射的类型:

var types = typeof(Customer).Assembly.GetTypes()
    .Where(t => t.Namespace == typeof(Customer).Namespace);

8. 创建一个类型为ObjectRelationalMapper的实例,如下面的代码所示:

var orm = new ObjectRelationalMapper();

9. 告诉映射器,应该为每一个类型创建一个表,如下所示:

orm.TablePerClass(types);

10. 创建映射,并将它们添加到配置对象,如下面的代码所示:

var mapper = new Mapper(orm);
var hbmMappings = mapper.CompileMappingFor(types);
configuration.AddDeserializedMapping(hbmMappings, "MyDomain");

11. 创建schema生成脚本,如下面的代码所示:

var exporter = new SchemaExport(configuration);
exporter.Execute(true, false, false);

12. 同样,添加下面的代码为避免程序未经确认就退出:

Console.Write("按回车退出:");
Console.ReadLine();

13. 运行程序,如下图所示:

ConfORM

没用编码和少量的配置,我们就使系统为我们的领域模型创建了一个隐式的映射,并导出为可以创建数据库架构的脚本。生成的脚本基于定义在ConfORM中的约定。所有的这些约定都可以重写,也可以根据需要添加自己的约定。

自动映射到此为止,下一篇介绍XML映射。

posted @ 2011-11-14 21:10  BobTian  阅读(3837)  评论(4编辑  收藏  举报