簡體   English   中英

將同一實體映射到不同的表

[英]Mapping the same entity to different tables

一點領域知識

我正在編寫一個 POS(銷售點)軟件,它允許支付貨物或退款。 在付款或退款時,需要指定使用哪種匯款方式:現金、EFT(~=信用卡)、會員卡、代金券等。

這些匯款方式是一組有限且已知的值(一種枚舉)。

棘手的部分是我需要能夠在 POS 終端上存儲這些方式的自定義子集,用於付款和退款(兩組可能不同)。

例如:

  • 可用的付款方式:現金、電子轉帳、會員卡、代金券
  • 可用退款方式:現金、代金券

實施現狀

我選擇實現匯款方式的概念如下:

public abstract class MoneyTransferMean : AggregateRoot
{
    public static readonly MoneyTransferMean Cash = new CashMoneyTransferMean();
    public static readonly MoneyTransferMean EFT = new EFTMoneyTransferMean();
    // and so on...

    //abstract method

    public class CashMoneyTransferMean : MoneyTransferMean
    {
        //impl of abstract method
    }

    public class EFTMoneyTransferMean : MoneyTransferMean
    {
        //impl of abstract method
    }

    //and so on...
}

它不是“普通枚舉”的原因是這些類內部存在一些行為。 我還必須將內部類聲明為 public(而不是私有),以便在 FluentNHibernate 映射中引用它們(見下文)。

如何使用

支付和退款手段總是作為一個集合存儲在/從數據庫中檢索。 它們實際上是兩個不同的集合,即使兩個集合中的某些值可能相同。

用例 1:定義一組新的支付/退款方式

  • 刪除所有現有的支付/退款方式
  • 插入新的

用例2:檢索所有支付/退款方式

  • 獲取所有存儲的付款/退款方式的集合

問題

我在持久性方面堅持我目前的設計。 我正在使用 NHibernate(使用 FluentNHibernate 來聲明類映射),但找不到將其映射到某些有效數據庫模式的方法。

我發現可以使用entity-name多次映射一個類,但是我不確定子類是否可行。

我還沒有准備好改變 MoneyTransferMean 公共 API 以使其能夠持久化(例如添加bool isRefund以區分兩者)。 但是,添加一些私有鑒別器字段左右是可以的。

我目前的映射:

public sealed class MoneyTransferMeanMap : ClassMap<MoneyTransferMean>
{
    public MoneyTransferMeanMap()
    {
        Id(Entity.Expressions<MoneyTransferMean>.Id);
        DiscriminateSubClassesOnColumn("Type")
            .Not.Nullable();
    }
}

public sealed class CashMoneyTransferMeanMap : SubclassMap<MoneyTransferMean.CashMoneyTransferMean>
{
    public CashMoneyTransferMeanMap()
    {
        DiscriminatorValue("Cash");
    }
}

public sealed class EFTMoneyTransferMeanMap : SubclassMap<MoneyTransferMean.EFTMoneyTransferMean>
{
    public EFTMoneyTransferMeanMap()
    {
        DiscriminatorValue("EFT");
    }
}

//and so on...

這個映射編譯但是它只生成 1 個表,在查詢這個表時我無法區分付款/退款。

我試圖聲明兩個映射,引用具有不同表和實體名稱的MoneyTransferMean但這導致我出現異常Duplicate class/entity mapping MoneyTransferMean+CashMoneyTransferMean

我還嘗試復制子類映射,但我無法指定“父映射”,這導致我遇到與上述相同的異常。

是否存在保留我當前域實體的解決方案?

如果不是,我需要對我的實體執行的最小重構是什么,以使它們與 NHibnernate 保持一致?

為什么不創建一個具有所有通用屬性(字段)的單一實體MoneyTransferMean ,然后添加 2 個額外字段(布爾值)來確定 MoneyTransferMean 是 Payment 還是 Refund,還是兩者兼而有之???? 堅持與否。

也可以使用帶有 Id (PK) 的額外實體來完成,添加相同的額外字段,與 MoneyTransferMean 的關系將是 1:1。 丑陋,我知道,但它應該工作。

我想補充一下@DEVX75 的建議,因為您的交易類型基本上描述了相同的概念,盡管一個是 +ve 而另一個是 -ve。 不過,我可能只添加一個布爾字段,並有單獨的記錄來區分退款和付款。

假設您有一個 UID 並且沒有使用手段標簽名稱作為 ID,您可以允許手段重復名稱,並包括兩個現金條目,例如:

UID、標簽、IsRefund

1、現金、假

2、現金,真實

3、代金券,假的

4、代金券,真實

然后您可以輕松獲得以下內容:

交易類型= MoneyTransferMean.IsRefund? “退款”:“付款”

交易價值= MoneyTransferMean.IsRefund? MoneyTransfer.amount * -1 : MoneyTransfer.amount

這樣,如果您在交易中引用了 MoneyTransferMean.UID = 2,您就知道這是現金退款,而不是知道這是一種可以是現金退款或現金支付的交易類型。

最后,我決定通過將我的實體MoneyTransferMean復制到兩個實體PaymentMeanRefundMean來解決這個問題。

雖然在實現上相似,但兩個實體之間的區別在業務中是有意義的,對我來說是最不糟糕的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM