关于域对象的存储库及其保存方法的问题

2024-01-26

我有一个关于 DDD、存储库模式和 ORM 的有点荒谬的问题。在这个例子中,我有 3 个类:Address, Company and Person。个人是公司的成员并拥有地址。公司也有地址。

这些类反映了数据库模型。我删除了模型的所有依赖项,因此它们不依赖于特定的 ORM 库,例如 NHibernate 或 LinqToSql。这些依赖关系在存储库内处理。

里面的一个存储库有一个保存人(人)方法其中插入/更新一个 Person 取决于它是否已经存在于数据库中。

由于 Person 对象有一个 Company,因此我当前在进行 SavePerson 调用时也会保存/更新 Company 属性的值。在此过程中,我插入/更新了公司的所有数据 - 名称和地址。

然而,我真的很难想象在处理个人时公司的数据可能会发生变化的情况 - 我只想能够将公司分配给个人,或者将个人移动到另一个公司。我认为我不想与新人一起创建一家新公司。因此 SaveCompany 调用会引入不必要的数据库调用。保存人员时,我应该能够更新 CompanyId 列。

但由于 Person 类有一个 Company 属性,我有点倾向于用它来更新/插入它。从严格/纯粹的角度来看,SavePerson 方法应该保存整个 Person。

首选的方式是什么?在保存 Person 或保存其所有数据时,仅插入/更新 Company 属性的 CompanyId 吗?或者您会为这两种情况创建两种不同的方法(您会给它们起什么名字?)

另外,还有一个问题,我目前有不同的方法来保存人员、地址和公司,所以当我保存公司时,我也会调用 SaveAddress。假设我使用 LinqToSql - 这意味着我不会在同一 Linq 查询中插入/更新公司和地址。我猜有 2 个 Select Calls(检查公司是否存在,检查地址是否存在)。然后对两者进行两次插入/更新调用。如果引入更多的复合模型类则更多。 LinqToSql 有没有办法优化这些调用?

public class Address
{
    public int AddressId { get; set; }
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public string City { get; set; }
    public string PostalCode { get; set; }        
}

public class Company
{
    public int CompanyId { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }
}


public class Person
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public Company Company { get; set; }
    public Address Address { get; set; }

}

Edit

另请参阅这个后续问题 https://stackoverflow.com/questions/679005/how-are-value-objects-stored-in-the-database。值对象如何存储在数据库中?


我自己最近使用了 Keith 建议的 IRepository 方法。但是,您不应该在这里关注这种模式。相反,DDD 手册中还有一些内容可以在这里应用。

使用值对象作为您的地址

首先,您可以在这里应用值对象(VO)的概念。在您的情况下,它将是地址。值对象和实体对象之间的区别在于实体具有身份; VO 则不然。 VO 的身份实际上是其属性的总和,而不是唯一的身份。在书里快速领域驱动设计 https://rads.stackoverflow.com/amzn/click/com/1411609255(它也是一个免费的 PDF 下载),他很好地解释了这一点,指出地址实际上只是地球上的一个点,不需要像人一样单独的类似社会保障的身份。地球上的那个点是街道、号码、城市、邮政编码和国家/地区的组合。它可以具有纬度和经度值,但根据定义,这些值仍然是 VO,因为它是两点的组合。

Use Services用于将您的实体合并为一个实体以进行操作。

另外,不要忘记 DDD 手册中的服务概念。在您的示例中,该服务将是:

public class PersonCompanyService
{
  void SavePersonCompany(IPersonCompany personCompany)
  {
    personRepository.SavePerson();
    // do some work for a new company, etc.
    companyRepository.SaveCompany();
  }
}

当您有两个实体都需要类似的操作来协调其他操作的组合时,就需要服务。在您的情况下,保存 Person() 并同时创建一个空白 Company() 。

ORM 通常需要一个身份、句点。

现在,您将如何将地址 VO 保存到数据库中?显然您会使用 IAddressRepository。但由于大多数 ORM(即 LingToSql)要求所有对象都有一个身份,因此技巧如下:将身份标记为模型中的内部身份,这样它就不会暴露在模型层之外。这是史蒂文·桑德森自己的建议。

public class Address
{
  // make your identity internal
  [Column(IsPrimaryKey = true
    , IsDbGenerated = true
    , AutoSync = AutoSync.OnInsert)]
  internal int AddressID { get; set; }

  // everything else public
  [Column]
  public string StreetNumber { get; set; }
  [Column]
  public string Street { get; set; }
  [Column]
  public string City { get; set; }
  ...
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于域对象的存储库及其保存方法的问题 的相关文章

随机推荐

  • 寻找 C++ 的应用程序 GUI 库 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在考虑编写一个非常简单的绘画程序 我想要一种更高级的方法来将数据输入到我的程序中 例如颜色 画笔的
  • 命名空间“卡住”为终止,我如何删除它

    我有一个 卡住 的命名空间 我删除了它 显示在这个永恒的 终止 状态中 假设您已经尝试强制删除资源 例如 Pod 停留在终止状态 https stackoverflow com q 35453792 而你却束手无策地试图恢复名称空间 您可以
  • 命令行从 TFS“获取最新”,无需映射工作区等

    我假设 tf exe get project recursive 需要这个奇怪的工作区映射 已知的 TFS 服务器等 有什么办法可以做这个最简单的事情 连接到thisTFS 服务器使用this一组凭据 获取最新的源代码this项目并把它he
  • 如何从程序窗口外部获取鼠标事件

    我想拖动这个角色 图像 所以我使用这个方法来获取鼠标位置 WndProc HWND hWnd UINT message WPARAM wParam LPARAM lParam switch message case WM LBUTTONDO
  • 具有白色轮廓的 OpenGL 彩色位图字体

    我有一个 libgdx 游戏 我想在其中使用带有轮廓的位图字体 我希望能够使用 setColor 设置字体颜色 但是 我总是希望轮廓保持白色 对我来说实现这一目标的最佳方法是什么 我假设我应该使用片段着色器进行所需的颜色操作 我创建了一个位
  • 在finally块中抛出异常

    有没有一种优雅的方式来处理抛出的异常finally block 例如 try Use the resource catch Exception ex Problem with the resource finally try resourc
  • 找不到方法 android java.lang.NoClassDefFoundError 引用的类

    我正在调用一个单独的类 我已经在与我的包相同的包中编写了MainActivity类已保存 但是当我运行该应用程序时它给了我java lang NoClassDefFoundError 我不明白为什么无法识别同一包中定义的另一个类 我尝试过很
  • 在使用关联类型的情况下,如何为通用容器实现 Borrow?

    我想实施Borrow for UserFriendlyDataStructure提供对internal data函数内的字段应该与数据提供者无关 的类型internal data字段由与特征相关的类型决定TraitA 请注意 Sealed特
  • X500主要杰出姓名顺序

    我使用 Bouncycastle 库通过 X509v3CertificateBuilder 类从 PKCS10 请求生成证书 它返回构建一个包含生成的证书的 X509CertificateHolder 对象 如果我在持有者上调用 getIs
  • SoundCloud 自动在其移动网站上播放下一首歌曲如何?

    好的 我知道 iOS 不允许自动播放 但是 SoundCloud 如何在其移动网站上自动播放下一首歌曲呢 我可以获得我想要填充 iframe src 的下一首歌曲 并且小部件会重新加载以显示该曲目 我尝试了很多解决方法 即使我在下一首曲目准
  • Python 脚本的桌面启动器以错误的路径启动程序

    我无法从 Linux Mint 17 1 Cinnamon 上创建的 desktop 启动器启动 python 脚本 问题是脚本将在错误的路径中启动 即主文件夹而不是它所在的目录 因此 它无法在其文件夹中找到伴随它的其他重要文件 因此无法工
  • 检查列表是否由 X 的 N 个实例组成(重复 X N 次)

    给定一个查询 例如 containsN 4 2 Z 我应该得到 Z 2 2 2 2 or containsN 4 W 3 3 3 3 我应该得到 W 3 换句话说 对于第一个示例 我需要绑定到 Z 的列表中 2 的 4 个实例 对于第二个示
  • 使用 Python 从法语 Word 文档中提取 XML 时出现问题:生成非法字符

    在过去的几天里 我一直在尝试创建一个脚本 该脚本将 1 从 Word 文档中提取 XML 2 修改该 XML 3 使用新的 XML 创建并保存新的 Word 文档 在许多 stackoverflow 用户的帮助下 我最终找到了看起来非常有前
  • 如何在 iPadOS15 safari 中禁用放大镜

    我想禁用当我们长按任何 html 元素时出现的文本放大镜 它开始再次出现在 iOS 15 中 我尝试了以下方法 但在 iOS 15 上不起作用 在 iOS html 应用程序中禁用放大镜 https stackoverflow com qu
  • OSGi 配置管理服务的现有实现?

    我们正在考虑使用配置管理服务作为主要 API 用于配置基于 OSGi 的应用程序中的组件 如果我们可以重用一些现有的实现 那就太好了 所以我正在尝试调查和评估最受欢迎的实现 我知道有 Apache Felix 配置管理 http felix
  • UIPageViewController/TextKit 在分页上回流文本

    我正在开发一个由 TextKit 支持的多页阅读应用程序 该应用程序基于 WWDC 2013 的 Advanced Text Layouts and Effects with Text Kit 会议 但有些代码是根据不完整的示例重建的 基本
  • 为什么我应该更喜欢 `Option::ok_or_else` 而不是 `Option::ok_or`?

    我刚刚在拉取请求中看到以下更改 ok or Error new ErrorKind Other Decode error ok or else Error new ErrorKind Other Decode error 我知道的唯一区别是
  • 使 ASP.Net 中的 URL 对用户友好

    我正在尝试使用 Web 窗体在 ASP Net 中开发我的第一个网站 我有一个带有一些控件和一个 TextBox 控件的表单 虽然现在我用GET要求 当用户提交表单时 他的浏览器期望获得长 URL 例如 http mysite com se
  • 如何使用 Gradle 创建具有实现依赖项的可执行 fat JAR?

    我在 Gradle 4 6 中有一个简单的项目 想为其制作一个可执行的 JAR 我试过了shadow gradle fatjar plugin gradle one jar spring boot gradle plugin插件 但它们都没
  • 关于域对象的存储库及其保存方法的问题

    我有一个关于 DDD 存储库模式和 ORM 的有点荒谬的问题 在这个例子中 我有 3 个类 Address Company and Person 个人是公司的成员并拥有地址 公司也有地址 这些类反映了数据库模型 我删除了模型的所有依赖项 因