2011-03-22 125 views
2

我遇到與繼承使用Fluent NHibernate自動映射的問題。以下是我的實體設置(縮寫爲簡單起見)。我已經配置了Fluent NHibernate爲帶有鑑別器列的層次結構創建1個類。當我生成一個數據庫時,自動映射看起來工作正常,一個表被創建爲名爲「AddressBase」的鑑別器列,該列標識每行是什麼類型的地址。Fluent NHibernate自動映射與子類關係的繼承

問題在於,當我在UserAccount類上調用方法「GetPrimaryBillingAddress()」時,NHibernate正在創建一個查詢帳單和發貨地址的查詢,而不僅僅是查詢帳單地址。它根本沒有考慮到鑑別器。我假設有某種配置可以設置,但一直沒能找到任何東西。

public abstract class AddressBase : ActiveRecord<AddressBase> 
{ 
    public virtual long Id { get; set; } 

    public virtual string Address1 { get; set; } 

} 

public class AddressBilling : AddressBase 
{ 
    public class TypedQuery : ActiveRecordQuery<AddressBilling> { } 

    public virtual bool IsPrimary { get; set; } 
} 

public class AddressShipping : AddressBase 
{ 
    public class TypedQuery : ActiveRecordQuery<AddressShipping> { } 

    [Display(Name = "Is Primary")] 
    public virtual bool IsPrimary { get; set; } 

} 

public class UserAccount : ActiveRecord<UserAccount> 
{ 
    public virtual long Id { get; set; } 

    public virtual IList<AddressBilling> BillingAddresses { get; set; } 
    public virtual IList<AddressShipping> ShippingAddresses { get; set; } 

    public UserAccount() 
    { 
     BillingAddresses = new List<AddressBilling>(); 
     ShippingAddresses = new List<AddressShipping>(); 
    } 

    public virtual AddressBilling GetPrimaryBillingAddress() 
    { 
     if (BillingAddresses.Any(x => x.IsPrimary)) 
     { 
      return BillingAddresses.Single(x => x.IsPrimary); 
     } 

     return BillingAddresses.FirstOrDefault(); 
    } 

    public virtual AddressShipping GetPrimaryShippingAddress() 
    { 
     if (ShippingAddresses.Any(x => x.IsPrimary)) { 
      return ShippingAddresses.Single(x => x.IsPrimary);    
     } 

     return ShippingAddresses.FirstOrDefault(); 
    } 

} 

UPDATE: 這裏是在自動映射中使用的映射覆蓋功能:

private static FluentConfiguration GetFluentConfiguration(string connectionStringName = "CS") 
{ 
     var autoMapping = AutoMap 
      .AssemblyOf<Product>(new Mapping.AutoMappingConfiguration()) 
      .Conventions.Setup(c => 
      { 
       c.Add<Mapping.ForeignKeyConvention>(); 
       c.Add<Mapping.DiscriminatorConvention>(); 
      }) 
      .IgnoreBase<AddressBilling.TypedQuery>() 
      .IgnoreBase<AddressShipping.TypedQuery>() 
      .IncludeBase<AddressBase>(); 

     return Fluently.Configure() 
      .Database(MsSqlConfiguration.MsSql2005.ConnectionString(c => c.FromConnectionStringWithKey(connectionStringName))) 
      .Mappings(m => m.AutoMappings.Add(autoMapping)); 
} 

public class AutoMappingConfiguration : DefaultAutomappingConfiguration 
{ 
    public override bool ShouldMap(Type type) 
    { 
     var isStatic = type.IsAbstract && type.IsSealed; 

     return type.Namespace == typeof(Entities.Product).Namespace && !isStatic; 
    } 

    public override bool IsDiscriminated(Type type) 
    { 

     if (type == (typeof(Entities.AddressBase))) { 
      return true; 
     } 

     return false; 
    } 

    public override string GetDiscriminatorColumn(Type type) 
    { 
     return "Type"; 
    } 

public class DiscriminatorConvention : ISubclassConvention 
{ 
    public void Apply(ISubclassInstance instance) 
    { 
     //Address 
     if (instance.Name == typeof(AddressBilling).AssemblyQualifiedName) 
     { 
      instance.DiscriminatorValue(Enums.AddressType.BillingAddress); 
     } 
     else if (instance.Name == typeof(AddressShipping).AssemblyQualifiedName) 
     { 
      instance.DiscriminatorValue(Enums.AddressType.ShippingAddress); 
     } 
    } 
} 

謝謝!

+0

如何映射UserAccount的屬性BillingAddresses和ShippingAddresses?你有他們的一些映射覆蓋? – Serhiy 2011-03-23 12:19:39

+0

更新後的帖子包括映射覆蓋。 – Jeremy 2011-03-23 13:32:02

回答

2

請試着改變你的類UserAccount是這樣的:

public class UserAccount : ActiveRecord<UserAccount> 
{ 
    public virtual IList<AddressBase> Addresses { get; set; } 
    public virtual IList<AddressBilling> BillingAddresses { get {return this.Addresses.OfType<AddressBilling>();} } 
    public virtual IList<AddressShipping> ShippingAddresses { get {return this.Addresses.OfType<AddressShipping>();} } 
    // ... 
} 

當然,只有地址屬性應該在這裏映射。

+0

感謝您的幫助! – Jeremy 2011-03-23 20:45:31

+0

不客氣) – Serhiy 2011-03-24 13:54:48

相關問題