2011-03-22 150 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

相关问题