前言
使用nhibernate在项目中不管是代码或者xml文件映射方式,如果项目较大编写映射也应该算一笔大的工作量了,使用Fluent Nhibernate自己编写映射规则,将从conventions添加到默认automappingd的规则中,根据规则生成映射,这样可以避免我们编写大量的映射文件。
步骤
1、编写规则指定生成的数据库架构并且生成数据库映射。举例生成如下数据库关系的映射:
2、编写需要映射的持久化模型
基类(只映射继承该基类的模型):
public abstract class Entity { virtual public int ID { get; set; } }
需要映射的模型:
public class User:Entity { virtual public string Name { get; set; } virtual public string No { get; set; } } public class Project:Entity { public Project() { Task = new I.HashedSet<Task>(); } virtual public string Name{ get;set;} virtual public User User { get; set; } virtual public ICollection<Task> Task { get; set; } } public class Task:Entity { virtual public string Name { get; set; } virtual public Project Project { get; set; } }
3、实现自定义映射规则
指定需要映射的类型,继承默认的DefaultAutomappingConfiguration,重写ShouldMap()方法,只映射实现Entity的子类:
public class AutomappingConfiguration : DefaultAutomappingConfiguration { public override bool ShouldMap(Type type) { return type.IsSubclassOf(typeof(Entity)); } }
IClassConvention表名的生成规则:实体类名+“s”:
public class DefaultTableNameConvention : IClassConvention { public void Apply(IClassInstance instance) { instance.Table(instance.EntityType.Name+"s"); } }
IPropertyConvention:指定字符串属性生成表列的长度:
public class DefaultStringLengthConvention : IPropertyConvention { public void Apply(IPropertyInstance instance) { instance.Length(50); } }
IIdConvention:指定主键名称(类名+“ID”)及增长方式
public class DefaultPrimaryKeyConvention : IIdConvention { public void Apply(IIdentityInstance instance) { instance.Column(instance.EntityType.Name+"ID"); instance.GeneratedBy.Native(); } }
IReferenceConvention:外键引用,外键实体名称+“ID”,可以根据关系同步修改实体
public class DefaultReferenceConvention : IReferenceConvention { public void Apply(IManyToOneInstance instance) { instance.Column(instance.Name+"ID"); instance.LazyLoad(); } }
IHasManyConvention:one-to-many实体映射,级联删除等
public class DefaultHasManyConvention : IHasManyConvention { public void Apply(IOneToManyCollectionInstance instance) { instance.Key.Column(instance.EntityType.Name+"ID"); instance.Cascade.AllDeleteOrphan(); instance.LazyLoad(); } }
4、fluent nhibernate配置
指定需要映射的程序集并添加自动映射配置
private static AutoPersistenceModel CreateAutomappings() { return AutoMap .Assembly(Assembly.Load("Model"),new DefaultAutomappingConfiguration()) .Conventions.Setup(con => { con.Add<DefaultTableNameConvention>(); con.Add<DefaultPrimaryKeyConvention>(); con.Add<DefaultStringLengthConvention>(); con.Add<DefaultReferenceConvention>(); con.Add<DefaultHasManyConvention>(); }); }
创建session工厂方法:
public static ISessionFactory CreateSessionFactory() { return Fluently .Configure() .Database( MsSqlConfiguration .MsSql2008 .ConnectionString(c => c.FromConnectionStringWithKey("connstr"))//指定连接字符串 .ShowSql() ) .Mappings(m => m.AutoMappings.Add(CreateAutomappings()) .ExportTo("c:\path")//导出映射文件 ) //生成数据库架构 .ExposeConfiguration(cfg => new SchemaExport(cfg).Create(true, true)) .BuildSessionFactory(); }
5、单元测试
生成数据库架构:
保存数据,一对多关系级联保存:
外键修改:
级联删除:
结语:
开发过程中可以直接添加实体类所在程序集根据自定义重写的规则生成特定映射,一般在项目中经常出现映射文件的问题,可以到处自动映射的文件查看映射字段,在添加映射的时候重写映射解决某个字段映射不正确的问题,初试fluent nhibernate,下班时间比较仓促,代码粗略,也许有很多不合理的地方,欢迎指正交流。