[英]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
復制到兩個實體PaymentMean
和RefundMean
來解決這個問題。
雖然在實現上相似,但兩個實體之間的區別在業務中是有意義的,對我來說是最不糟糕的解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.