1

我有一个预先存在的数据库,我正在尝试使用 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();
4

1 回答 1

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())
于 2013-10-12T08:48:07.667 回答