如何在 Fluent NHibernate 中建模此对象层次结构而不违反 DDD 原则?

发布于 2024-09-18 18:53:29 字数 1809 浏览 13 评论 0原文

我正在尝试构建一个允许我管理合同的域模型。

Contract 类是我的聚合根,它现在有一个属性,即 Reviewers。

在合同上下文中,每个审阅者都拥有其父合同的属性以及名字、姓氏和登录名。他们拥有这些属性的原因是我可以让用户在合同上选择他们想要的审阅者。

我将域模型绑定到的数据库已经存在,并且它是我正在尝试扩展的遗留系统。

它有一个合同表和一个审阅者表。

到目前为止我还没有提到的是,审阅者实际上是系统中的用户。所以实际上涉及到第三个表,即用户。

我已经能够使用 FNH 轻松映射我的合同表。

它看起来像这样:

public class ContractMapping: ClassMap<Contract>
{
    public ContractMapping()
    {
        Id(c => c.Id);
        HasMany(c => c.AdditionalReviewers);
    }
}

但我不确定如何为我的审阅者建模,因为他们实际上也是用户。所以我的对象模型看起来像这样:

public class Reviewer: User
{
    public virtual Guid Id { get; set; }

    public virtual Contract Contract { get; set; }
}

public class User
{
    public virtual Guid Id { get; set; }

    public virtual string Login { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }        
}

我已经能够正确映射我的 User 类,它看起来像这样:

public class UserMapping: ClassMap<User>
{
    public UserMapping()
    {
        Id(u => u.Id);
        Map(u => u.Login);
        Map(u => u.FirstName);
        Map(u => u.LastName);
    }
}

我相信我想像这样映射我的 Reviewer 类:

public class ReviewerMapping: SubclassMap<Reviewer>
{
    public ReviewerMapping()
    {
        Table("Reviewer");

        //Id(r => r.Id).Column("ReviewerId"); <- won't compile
        References(r => r.Contract).Column("ContractId");
    }
}

所以我遇到的问题是这样的:

用户表和审阅者表之间的关系是一对多。这意味着,对于给定的用户,可能有许多审阅者记录。为什么?因为用户必须是特定合同的审阅者。但这会导致映射出现问题,因为我的审阅者的主键和我的用户的主键必然是完全不同的值。

另外,由于我使用审阅者的方式,当我创建新的审阅者时,我真正想做的是将用户与合同关联起来。我尝试在数据库中创建一个全新的用户。

知道在我的域模型中它是 User 的子类,映射 Reviewer 的正确方法是什么?

I am trying to build a domain model that will allow me to manage Contracts.

The Contract class is my aggregate root, and it has a single property right now, which is Reviewers.

Reviewers, in the context of the Contract, each have a property to it's parent Contract, and a First Name, Last Name, and Login. The reason they have these properties is so I can have the user select which Reviewers they want on a Contract.

The database that I'm tying my domain model to already exists, and it's a legacy system that I'm trying to extend.

It has a Contract Table, and a Reviewer Table.

The thing I haven't mentioned up until this point, is that Reviewers are actually Users in the system. So there's actually a third table involved, which is Users.

I have been able to map my Contract Table easily with FNH.

It looks something like this:

public class ContractMapping: ClassMap<Contract>
{
    public ContractMapping()
    {
        Id(c => c.Id);
        HasMany(c => c.AdditionalReviewers);
    }
}

But I'm not sure how to model my Reviewers, because they are in fact Users as well. So my object model looks like this:

public class Reviewer: User
{
    public virtual Guid Id { get; set; }

    public virtual Contract Contract { get; set; }
}

public class User
{
    public virtual Guid Id { get; set; }

    public virtual string Login { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }        
}

I've been able to map my User class properly, and it looks something like this:

public class UserMapping: ClassMap<User>
{
    public UserMapping()
    {
        Id(u => u.Id);
        Map(u => u.Login);
        Map(u => u.FirstName);
        Map(u => u.LastName);
    }
}

and I believe I want to map my Reviewer class like this:

public class ReviewerMapping: SubclassMap<Reviewer>
{
    public ReviewerMapping()
    {
        Table("Reviewer");

        //Id(r => r.Id).Column("ReviewerId"); <- won't compile
        References(r => r.Contract).Column("ContractId");
    }
}

So the problem I'm having is this:

The relationship between the User table and the Reviewer table is one to many. Meaning, for a given User there may be many Reviewer records. Why? Because a User has to be a Reviewer for a specific Contract. This causes an issue with the mapping, though, because the primary key for my Reviewer and the primary key for my User are completely different values, by necessity.

Also, because of the way I'm using Reviewer, when I create a new Reviewer, what I'm really trying to do is to associate a User with a Contract. I am not trying to create an entirely new User in the database.

What is the correct way for me to map Reviewer, knowing that in my domain model it is a subclass of User?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷了相思 2024-09-25 18:53:29

听起来审阅者实际上并不是在建模一个人,而是在建模用户所承担的角色或任务。我想说你的领域模型在这方面是有缺陷的。将 Reviewer 调整为用户和合约之间的关联类。

Sounds like a the Reviewer is not really modelling a person, but modelling a role or assignment the User takes on. I'd say your domain model is flawed in this aspect. Tweak Reviewer to be an association class between a User and a Contract.

叶落知秋 2024-09-25 18:53:29

我认为在您描述的场景中 Reviewer 不应该继承 User 。我会让 Reviewer 类持有一个 User 对象(组合优于继承)。

如果它可以帮助您更好地概念化它,请将审阅者重命名为 Review。这样您就可以停止将其视为用户,因为它实际上不是(当前域中的多个审阅者可以是同一用户,这没有多大意义)。

I don't think Reviewer should inherit from User in the scenario you've described. I would have the Reviewer class hold a User object instead (composition over inheritance).

If it helps you conceptualize it better, rename Reviewer to Review. That way you can stop thinking about it as a User since it really isn't (multiple Reviewers in your current domain can be the same User, which doesn't make much sense).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文