2

我看過很多關於SO和google的問題,關於nhibernate/fluent-nhibernate中的子類映射,並沒有設法找到任何與我相同問題的人。我遵循fluent-nhibernate維基(http://wiki.fluentnhibernate.org/Fluent_mapping#Subclasses)的基本說明,但這沒有幫助。我有一個名爲Operation的基本實體 - 它有一個基表與它關聯,然後我有子表UnpaidCheque,退款等 - 這些子表的主鍵是一個外鍵,OperationId (PK)從操作表中。Fluent NHibernate - 如何使用鑑別器創建每個子類的映射?

當我創建持久性規範並嘗試驗證映射時,它試圖將所有列保存到Operation表中,而不是保存到Operation表中,然後將Unpaid Check的特定列保存到UnpaidCheque表中。

的錯誤是:

could not insert: [UnpaidCheque][SQL: INSERT INTO Account.Operation (PaymentId, Amount, UnpaidOn, UnpaidByUserId, OperationType) VALUES (?, ?, ?, ?, 'U'); select SCOPE_IDENTITY()] 
    ----> System.Data.SqlClient.SqlException : Invalid column name 'UnpaidOn'. 
Invalid column name 'UnpaidByUserId'. 

正如你所看到的,它試圖保存UnpaidByUserId和UnpaidOn列它們是子表/類的成員,而不是基礎值。

另一方面,它試圖在操作類型列中插入'U'這一事實表明它似乎正在爲類類型設置正確的描述符值。我指定操作類型的唯一地方是在類映射的DiscriminatorValue()調用中,我沒有明確地在其他地方設置它。

類層次結構如下所示:

public class Operation 
    { 
     public virtual long OperationId { get; set; } 
     public virtual string OperationType { get; set; } 
     public virtual long? PaymentId { get; set; } 
     public virtual decimal Amount { get; set; } 
    } 

public class UnpaidCheque : Operation 
    { 
     public virtual DateTime UnpaidOn { get; set; } 
     public virtual long UnpaidByUserId { get; set; } 
    } 

類映射是:

public class OperationMap : ClassMap<Operation> 
    { 
     public OperationMap() 
     { 
      Schema("Account"); 
      Table("Operation"); 
      LazyLoad(); 
      Id(_ => _.OperationId).Column("OperationId").GeneratedBy.Identity(); 
      Map(_ => _.PaymentId).Column("PaymentId").Nullable(); 
      Map(_ => _.Amount).Column("Amount").Not.Nullable(); 

      DiscriminateSubClassesOnColumn("OperationType"); 
     } 
    } 
public class UnpaidChequeMap : SubclassMap<UnpaidCheque> 
{ 
    public UnpaidChequeMap() 
     { 
      Schema("Account"); 
      Table("UnpaidCheque"); 
      LazyLoad(); 
      DiscriminatorValue("U"); 
      KeyColumn("OperationId"); 
      Map(_ => _.UnpaidOn).Column("UnpaidOn").Not.Nullable(); 
      Map(_ => _.UnpaidByUserId).Column("UnpaidByUserId").Not.Nullable(); 
     } 
} 

我什麼都看不到,我從不是另外的其他例子做不同KeyColumn()在子類映射中,但是我沒有得到相同的錯誤消息。任何人都可以闡明我錯過了什麼,或者我試圖實現的目標是否受到nhibernate的支持?據我所知它應該是。

在此先感謝!

+0

操作應該是抽象的 – cgreeno 2012-03-27 12:23:33

+1

BTW你列的顯式設置是多餘的沒有?你可以只是映射(_ => _.PaymentId).Nullable() - 沒有指定列(「PaymentId」),它會工作一樣嗎? – PandaWood 2014-02-10 01:20:54

+0

@PandaWood - 是的,這是正確的,這只是個人喜好,我明確地映射列,但流利的假設,如果你沒有明確地設置它的屬性和列被命名爲相同。 – 2014-11-10 16:20:42

回答

1

我們找到了解決辦法:

Descriminators只對其中所有的子類都存儲在同一個數據庫中的表映射。

刪除線:

DiscriminateSubClassesOnColumn("OperationType"); 

從父映射和

DiscriminatorValue("U"); 

從子映射,然後除去從數據庫中列解決的問題。

+1

關於nhibernate文檔的章節[8.1.3](http://nhibernate.info/doc/nhibernate-reference/inheritance.html)怎麼樣?它表明可以使用_table每個子類繼承映射_with一個鑑別器_。儘管如此,我還是無法用流利的nhibernate來解決問題。 – bounav 2016-05-11 11:09:04

+0

@bounav如果你還有興趣,請看我的答案。 – AlexDev 2017-01-27 14:23:33

1

要使用表每個子類有鑑別了以下工作:

public class UnpaidChequeMap : SubclassMap<UnpaidCheque> 
{ 
    public UnpaidChequeMap() 
    { 
     Schema("Account"); 
     DiscriminatorValue("U"); 
     Join("UnpaidCheque", j => 
     { 
      j.KeyColumn("OperationId"); 
      j.Map(_ => _.UnpaidOn).Column("UnpaidOn").Not.Nullable(); 
      j.Map(_ => _.UnpaidByUserId).Column("UnpaidByUserId").Not.Nullable(); 
     } 
    } 
} 
相關問題