1

我有一個預先存在的數據庫,我正在嘗試使用Fluent NHibernate自動映射。很多的表都有審計列,所以我認爲將是合理的是許多實體繼承一個簡單的抽象類是這樣的:流利的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(); 
+0

也許您可以使用可以爲空的DateTime?或者您可以創建攔截器來填充必要的字段 – Alex

+0

將屬性設置爲空可以解決問題,是的,但它不是數據庫模式的真實表示。 db是填充字段的數據庫,所以我不想在C#中做任何事情來改變它們。 – adhocgeek

回答

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()) 
相關問題