2011-02-16 61 views
1

我想這個類映射:Nhibernate繼承映射混合Type-Per-Hierarchy和Type-Per-Class?

public interface IBusinessObject 
{ 
    Guid Id { get; set; } 
} 
public class Product 
{ 
    public virtual Guid Id { get; set; } 
    public virtual int ProductTypeId { get; set; } 
} 
public class ProductWeSell : Product, IBusinessObject 
{ 
} 
public class ProductWeDontSell : Product 
{ 
} 

爲數據庫2個表:

[BusinessObject] COLUMNS ([Id]) 
[Product] COLUMNS ([Id], [ProdyctTypeId]) 

我想有型每級的BusinessObject的,和類型每層次與產品。這將導致此行爲:

  • 添加產品:INSERT INTO產品{GUID),空}
  • 添加ProductWeDontSell:INSERT INTO產品{GUID,2}
  • 添加ProductWeSell:INSERT INTO BusinessObject的{GUID }; INSERT INTO產品{SameGuid,1}

按道理HBM映射應該是:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> 
    <class xmlns="urn:nhibernate-mapping-2.2" name="IBusinessObject" table="BusinessObject"> 
    <joined-subclass name="ProductWeSell" table="Product"/> 
    </class> 
</hibernate-mapping> 

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> 
    <class xmlns="urn:nhibernate-mapping-2.2" discriminator-value="null" name="Product" table="Product"> 
    <discriminator type="String"> 
     <column name="ProductTypeId" not-null="false" /> 
    </discriminator> 
    <subclass name="ProductWeDontSell" discriminator-value="2" /> 
    <subclass name="ProductWeSell" discriminator-value="1" /> 
    </class> 
</hibernate-mapping> 

,但我得到{ 「重複類/實體映射ProductWeSell」}錯誤。

+0

剛剛學習這個,你有沒有想過用IMappingOverride做什麼? http://wiki.fluentnhibernate.org/Auto_mapping – kenny 2011-02-16 11:20:21

+0

@kenny,不,我有聽說過IMappingOverride,但我知道有IAutoMappingOverride,但我不使用自動映射。 – 2011-02-16 11:24:17

回答

0

我來到了有趣的結論。我決定改變我的體系結構,併爲數據訪問層和域UI層使用單獨的類,我只是在我的對象穿過層時才轉換。任何方式都有一個很好的做法來解耦數據訪問和UI。所以我的數據訪問模型現在很簡單,沒有任何繼承,繼承只出現在域UI級別。

1

我相當肯定,與流利NHibernate這不能做到。當我試圖想出一個方法時,我創建了以下TestFixture。另外我不確定你想要映射什麼。如果您打算爲系統中的每個實體使用IBusinessObject,則IBusinessObject似乎是多餘的(CreateQuery(「from object」)將返回從對象繼承的每個實體,即所有內容)

注意:目前,這在IBusinessObject查詢它應該因爲它沒有被映射)。我不太確定,爲什麼沒有映射IBusinessObject接口,因爲隱式多態似乎應該覆蓋它(請參閱:http://nhibernate.info/doc/nh/en/index.html#inheritace-mixingpolymorphism),否則無法工作。

[TestFixture] 
public class TestFixture 
{ 

    private ISessionFactory _sessionFactory; 
    private ISession _session; 
    [SetUp] 
    public void Setup() 
    { 
     var fluentConfig = Fluently.Configure().Database(() => SQLiteConfiguration.Standard.InMemory().Provider<TestConnectionProvider>()) 
            .Mappings(x=>x.FluentMappings.Add<ProductMap>() 
                   .Add<ProductWeSellMap>() 
                   .Add<ProductWeDontSellMap>()); 
     var nhConfig = fluentConfig.BuildConfiguration(); 
     _sessionFactory = fluentConfig.BuildSessionFactory(); 

     var schema = new SchemaExport(nhConfig); 
     schema.Execute(false, true, false); 

     _session = _sessionFactory.OpenSession(); 
    } 

    [Test] 
    public void SomeTest() 
    { 
     using (var itx = this._session.BeginTransaction()) 
     { 
      var productSold = new ProductWeSell(); 
      var productNotSold = new ProductWeDontSell(); 
      _session.Save(productNotSold); 
      _session.Save(productSold); 
      itx.Commit(); 
     } 

     using (var itx = this._session.BeginTransaction()) 
     { 
      Assert.That(_session.CreateQuery("from ProductWeSell").List(), Has.Count.EqualTo(1)); 
      Assert.That(_session.CreateQuery("from ProductWeDontSell").List(), Has.Count.EqualTo(1)); 
      Assert.That(_session.CreateQuery("from IBusinessObject").List(), Has.Count.EqualTo(1)); 
      Assert.That(_session.CreateQuery("from Product").List(), Has.Count.EqualTo(2)); 
     } 
    } 
} 

public interface IBusinessObject 
{ 
    Guid Id { get; set; } 
} 

public class Product 
{ 
    public virtual Guid Id { get; set; } 
    public virtual int ProductTypeId { get; set; } 
} 
public class ProductMap : ClassMap<Product> 
{ 
    public ProductMap() 
    { 
     this.Id(x => x.Id); 
     this.DiscriminateSubClassesOnColumn("ProductTypeId"); 
    } 
} 

public class ProductWeSell : Product, IBusinessObject 
{ 
    public const int ProductWeSellTypeId = 1; 
} 

public class ProductWeSellMap : SubclassMap<ProductWeSell> 
{ 
    public ProductWeSellMap() 
    { 
     this.DiscriminatorValue(ProductWeSell.ProductWeSellTypeId); 
    } 
} 

public class ProductWeDontSell : Product 
{ 
    public const int ProductWeDontSellTypeId = 2; 
} 

public class ProductWeDontSellMap : SubclassMap<ProductWeDontSell> 
{ 
    public ProductWeDontSellMap() 
    { 
     this.DiscriminatorValue(ProductWeDontSell.ProductWeDontSellTypeId); 
    } 
} 

這將產生以下HBM映射:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true"> 
    <class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="CellTester.Test.Database.Product, Test, Version=2.0.0.3, Culture=neutral, PublicKeyToken=a15dc1b99998d28b" table="`Product`"> 
    <id name="Id" type="System.Guid, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
     <column name="Id" /> 
     <generator class="guid.comb" /> 
    </id> 
    <discriminator type="String"> 
     <column name="ProductTypeId" /> 
    </discriminator> 
    <subclass name="ProductWeSell, Test, Version=2.0.0.3, Culture=neutral, PublicKeyToken=a15dc1b99998d28b" discriminator-value="1" /> 
    <subclass name="ProductWeDontSell, Test, Version=2.0.0.3, Culture=neutral, PublicKeyToken=a15dc1b99998d28b" discriminator-value="2" /> 
    </class> 
</hibernate-mapping>