Fluent NHibernate无法从父类自动化数据库生成的属性

时间:2013-10-10 15:43:39

标签: c# nhibernate fluent-nhibernate fluent-nhibernate-mapping

我有一个预先存在的数据库,我正在尝试使用Fluent NHibernate自动化。许多表都有审计列,所以我认为合理的是许多实体继承了这样一个简单的抽象类:

public abstract class AuditableEntity
{
    public virtual string   CreatedBy { get; set; }
    public virtual DateTime CreatedOn { get; set; }
    public virtual string   ModifiedBy { get; set; }
    public virtual DateTime ModifiedOn { get; set; }
}

出现问题是因为这些值是在数据库中设置的,如果我尝试在不设置这些值的情况下插入新实体,我会得到SqlTypeException : SqlDateTime overflow,因为作为值类型,DateTime被初始化到DateTime.MinValue

我试图解决此问题的方法是添加一个自动覆盖,如下所示:

public class AuditableEntityOverride : IAutoMappingOverride<AuditableEntity>
{
    public void Override(AutoMapping<AuditableEntity> mapping)
    {
        mapping.Map(x => x.CreatedBy).Generated.Insert();
        mapping.Map(x => x.CreatedOn).Generated.Insert();
        mapping.Map(x => x.ModifiedBy).Generated.Always();
        mapping.Map(x => x.ModifiedOn).Generated.Always();
    }
}

然而,这实际上并没有做任何事情!

我可以通过显式覆盖继承审计列的每个实体的映射来解决问题,但这是很多实体,我试图让Fluent NHibernate完成大部分工作。

我可以采取哪些措施来强制执行所有子类的映射吗?

更新

如果它有帮助,这就是我创建会话工厂的方式。也许我在这里也缺少一些东西:

var sessionFactory = Fluently.Configure(new Configuration().AddProperties(new Dictionary<string, string>
{
    {Environment.ConnectionDriver,typeof (SqlClientDriver).FullName},
    {Environment.Dialect,typeof (MsSql2008Dialect).FullName},
    {Environment.ConnectionProvider,typeof (DriverConnectionProvider).FullName},
    {Environment.ConnectionString, connectionString},
    {Environment.ShowSql, "true"},
    {Environment.BatchSize, "100"},
    {Environment.Isolation,"ReadCommitted"}
}))
.Mappings(map => map.AutoMappings.Add(AutoMap.AssemblyOf<Transaction>(new AutomappingConfiguration())
                                            .Conventions.AddFromAssemblyOf<ReferenceConvention>()
                                            .Conventions.Add(DynamicUpdate.AlwaysTrue())
                                            .Conventions.Add(DynamicInsert.AlwaysTrue())
                                            .UseOverridesFromAssemblyOf<CurrencyOverride>))
.BuildSessionFactory();

1 个答案:

答案 0 :(得分:2)

您实际上应该能够通过实现IPropertyConvention接口并检查实例名称来编写自己的约定,例如:

public class DefaultAutiableConvention: IPropertyConvention
{
    public void Apply(IPropertyInstance instance)
    {
        if (instance.Name == "CreatedBy" || instance.Name == "CreatedOn")
        {
            instance.Generated.Insert();
        }
        else if (instance.Name == "ModifiedBy" || instance.Name == "ModifiedOn")
        {
            instance.Generated.Always();
        }
    }
}

然后将该约定添加到您的配置

.Conventions.Add(new DefaultAutiableConvention())