【发布时间】:2019-12-20 07:54:02
【问题描述】:
一点领域知识
我正在编写一个 POS(销售点)软件,它允许付款或退款。 付款或退款时,需要指定使用哪种汇款方式:现金、电子转帐(~=信用卡)、会员卡、代金券等。
这些汇款方式是一组有限且已知的值(一种枚举)。
棘手的部分是我需要能够在 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...
}
它不是“普通枚举”的原因是这些类中存在一些行为。为了在 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 持久化?
【问题讨论】:
-
为什么要将这些支付方式存储在数据库中?除了名字之外,那里的状态是什么?
-
@berhalak 实际上,将这些存储在数据库中看起来有点笨拙。然而,项目要求所有状态都在数据库中。
标签: c# nhibernate fluent-nhibernate domain-driven-design fluent-nhibernate-mapping