多个可为空的 Guid,其中只有一个可以有值

Posted

技术标签:

【中文标题】多个可为空的 Guid,其中只有一个可以有值【英文标题】:Multiple nullable Guid and only one of them can have a value 【发布时间】:2021-12-02 17:17:21 【问题描述】:

我有一个 FinancialAccount 类,它可以链接到其他三个类,或者手动生成,所以我实现了一个枚举来保存它所链接到的类的类型,以及其他三个可以为空的 Guid 来保存该链接类的 Guid

public enum AccountClassificaiton

    Normal,
    Bank,
    Contract,
    Employee,


public Account()

    ...
    public Guid Id  get; set; 
    public string Name  get; set; 
    public AccountClassificaiton AccountClassificaiton  get; set; 
    public Guid? ContractId  get; set; 
    public Guid? EmployeeId  get; set; 
    public Guid? BankAccountId  get; set; 
    ...

考虑到我无法将这些 Guid 从此类中移出,并且此类与这三个类之间存在一对一的关系,并且这些 Guid 中只有一个应该具有值,因此我需要一种更好的方法来解决此问题取决于这个类有什么 AccountClassification

对不起,我的英语不是母语

编辑-1

我在同一个解决方案上使用 8 个项目的领域驱动设计模式,所以我很难在没有法律问题的情况下向您展示真正的问题

编辑-2

这个项目是财务管理系统的一部分,是一个庞大的ERP系统的一部分

【问题讨论】:

听起来你想在你的模型中使用inheritance,采用“每层表”的方法,使用AccountClassification作为鉴别列。 有什么问题?如果它是约束,则在数据库中强制执行它。然而,这确实指向更大的架构设计气味......你真的需要指出实际问题是什么 (1) “我需要一个更好的方法来解决这个问题” 问题是什么?需要更好? (2)"考虑到我不能将这些Guids移出这个"如果你不能把字段移出类,我看不出你能做什么。一些提议的 TPH 继承,但是这些字段将在同一个 table 中,但在不同的 classes 中(这将是基础)。 我没有看到任何问题,一切都很好。我唯一不会使用的是枚举。如果还不是很晚,请创建一个特殊的表来代替它。 我只是不喜欢拥有多个可为空的 guid 的想法,并且感谢每个提出 TPH(按层次结构表)方法的人,我不知道存在这样的东西,我对 C# 有点陌生- EF-core,所以我还在学习,由于我签署了 NDA,我无法透露整个代码, 【参考方案1】:

我会设计不同的:

public enum AccountClassificaiton

    Normal,
    Bank,
    Contract,
    Employee,


public Account()

    ...
    public Guid Id  get; set; 
    public string Name  get; set; 
    public AccountClassificaiton AccountClassificaiton  get; set; 
    public List<Account> LinkedAccounts  get; set; 
    ...

类似的东西。

或者,如果您需要按帐户类型快速找到关联的帐户,您可以使用字典,其中键是 AccountClassificaiton 类型(值是 Account 对象)按类型对关联的帐户进行分组:

p>
public Dictionnary<AccountClassificaiton, Account> LinkedAccounts  get; set; 

当然,如果您有多个关联帐户,您可以缩进字典以获得更好的搜索效率:

public Dictionnary<AccountClassificaiton, Dictionnary<Guid, Account>> LinkedAccounts  get; set; 

或者使用自定义相等比较器处理 Guid 和 AccountClassificaiton 类型的复合键: https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.iequalitycomparer-1?view=net-5.0

【讨论】:

以上是关于多个可为空的 Guid,其中只有一个可以有值的主要内容,如果未能解决你的问题,请参考以下文章

可为空的对象必须具有一个值

在两个可为空的 FK 之间添加 SQL XOR 约束

序列化一个可为空的 int

可为空的对象必须具有一个值 是啥原因啊 求解 谢谢

为啥 TargetNullValue 更新可为空的 Source

JPA 可嵌入 PK 和可为空的字段