DDD with L2S or NHibernate... 关于业务对象的持久化数据

Posted

技术标签:

【中文标题】DDD with L2S or NHibernate... 关于业务对象的持久化数据【英文标题】:DDD with L2S or NHibernate... about persisting data of business objects 【发布时间】:2012-11-13 15:35:38 【问题描述】:

我一直在从事我的第一个实验性 DDD 项目。这个项目的目的是让我对整个 DDD 概念有一个感觉。奇怪的是,正如我所读的那样,它是更困难的部分,我发现无处不在的语言“翻译”比整个架构本身更容易,因此我的问题是。

我只在我过去的项目中使用过 L2S(Linq to SQL)。我的应用程序本身不是 DDD,但它们确实有一个业务对象(除了 linq to sql 生成的那些),而且我有一个用于该对象的存储库。例如,

public class Customer
    
       public ID get; set;
       public string Fullname get; set;
       public Address address get; set;
       public List<Invoices> invoices get; set;
    

现在,在 L2S 中,我必须将这个类分解为三个不同的查询并将它们提交到数据库中。我有一个映射器(扩展方法)让我的生活“更轻松”。像这样。

public void AddCustomer(Customer customer)

// This customer i am passing is the business object
// For the sake of demo, i am going to avoid the whole attach(), check for ID, etc.
// I think you are going to get what i am trying to do here.

using var context = new L2SContext())

context.CustomerEntity.InsertOnSubmit(customer.ToEntity());
context.AddressEntity.InsertOnSubmit(customer.Address.ToEntity());
context.InvoicesEntity.InsertAllOnSubmit(customer.Invoices.ToEntity());


好的。稍后我在上下文中有一个 SubmitChanges() 方法,我实际上将数据保存到数据库中。

现在,我对 NHibernate 知之甚少,几乎一无所知。 但是看一些例子,我怀疑 NHibernate 会为你处理所有的故障(因为映射?)所以你只需要传递 Customer 并且它会做剩下的事情。对吗?

如果我真的从中受益匪浅,我愿意学习 NHibernate。

感谢您查看我的问题。

编辑:您听说过 Codesmithtools.com 吗?他们有一个用于 LinqToSql、EF、NHibernate 的框架生成器。有人试过他们的 NHibernate 吗?我已经为 LinqToSql 使用了 PLINQO,但是它们给我认为不必要的类添加了很多废话。几乎这些类都适合用于糟糕的程序员,如业务类、DTO、ViewModels 等。多合一 :)。糟糕的。但是,他们真的很擅长生成所有这些。我必须为此给予他们 KUDOS。

【问题讨论】:

是的,您只需保存客户,NHibernate 就可以查看哪些发票和其他实体已更改,并且也会为您保存这些内容。当您不熟悉 NHibernate 时,有一个陡峭的学习曲线才能让事情发挥作用,但之后它是非常有益的。 谢谢杰克。我正在研究一些教程。我对流利的 nhibernate 和 nhibernate 以及 nhibernate MBC 感到困惑?你认为我需要哪一个? 我自己只使用普通的旧 NHibernate。发现 Fluent NHibernate 非常好,但是我正在开发的服务失败了,因为 fluent NHibernate 需要很长时间才能创建配置。那是几年前的事了,我敢肯定从那以后情况发生了变化。没有听说过 NHibernate MBC,所以不能对此发表评论。如果我现在开始一个绿地项目,我会从流利的 NHIbernate 开始。如有必要,迁移到普通的 NHibernate XML 配置并不难。 如果你想了解 DDD,不要使用数据库。如果你真的需要,在内存中使用一些东西。如果应用程序设计得当,那么添加一个真实的数据库应该很容易。不要错误地将 Nhibernate 实体视为域实体。 sapiensworks.com/blog/post/2012/04/20/…。顺便说一句,IMO 在任何地方都使用 ORM 并没有太大的好处。微型 Orm 可以完成您真正想要的所有事情,而且学习起来要容易得多 另请注意,DDD 实体通常没有公共设置器。您通过调用方法对实体执行操作。实体应该负责更新它的信息,而不是调用者。 【参考方案1】:

NHibernate over Linq-2-SQL for DDD 的几点:

可访问性的持久性。这也可以称为级联保存,但它允许您保留客户实体而无需显式插入它们。这非常适合 DDD,因为 Customer 将是一个聚合,而 Address 将是一个值对象。在 NHibernate 中,值对象表示为组件映射,实体和聚合表示为类映射。聚合应该作为单个单元进行持久化和检索,NHibernate 允许您这样做。

持久性无知。 NHibernate 允许您将您的类设计为纯 POCO,而无需引用其他库。据我记得,L2S 需要一个特殊的集合类型,并且需要明确的外键作为属性。请注意,即使使用 NHibernate persistence ignorance is an ideal, not a goal。

正如其他人所指出的,NHibernate 有一个陡峭的学习曲线。例如,lazy loading can be problematic。但总体来说还是值得的。

【讨论】:

【参考方案2】:

您的问题是开放式的。很明显,您现在了解 Linq-2-SQL 的工作原理。正如第一条评论所说:是的,NHibernate 可以提供级联保存。但这只是开始……请首先检查一下这个问题和答案(有趣的不止一个):

NHibernate vs LINQ to SQL

我在我的私人项目中使用NHibernate 作为首选。如果可能的话,我更喜欢在任何项目中使用它。但是,根据我的经验,我想再补充一个注意

最大的好处是,一旦您学习并使用NHibernate,使用其他ORM 工具就不会那么困难了。在某些项目中,您会(我确实)在一些 LLBL 生成器上遇到实体框架...,并且 (虽然我们可以责怪与 NHibernate 相比缺少某些东西;)我们可以快速:

了解领域,因为 ORM 强制实施实体/领域驱动 使用标准模式

希望 NHibernate 对您有所帮助并祝您好运。学习曲线可能比预期的要慢,但好处等待着。

【讨论】:

谢谢拉迪姆。我已经读过那篇文章了。现在的问题是,在阅读了 Fluent NHibernate、NHibernate MBC 之后……这是哪个?或者,哪一个是最好的。由于它是开源的,我想那里有多种变体。 是的 ;) 这是一个很好的问题。我尝试尽可能多地使用默认分布。例如。 XML映射,Criteria语言,强大的QueryOver。对于自定义需求,我们使用了扩展点(并且有很多类似的事件监听器)。但我从来没有发现使用流利映射、LINQ 提供程序之类的插件有用……因为所有这些都是建立在 NHibernate 之上的,试图隐藏 NHibernate 的一些困难——但很难说是否实现了。所以我个人建议从默认值开始。 @Tony 请参阅 ***.com/a/8294639/671619 了解有关 FluentNH 与 MBC 的一些事实 @Firo,精彩的话题!很好的阅读,很多事实。玩了fluent后最喜欢的还是xml。但这绝对是个人的

以上是关于DDD with L2S or NHibernate... 关于业务对象的持久化数据的主要内容,如果未能解决你的问题,请参考以下文章

Tackle Business Complexity in a Microservice with DDD and CQRS Patterns

使用 WCF/OData 作为访问层而不是直接使用 EF/L2S/nHibernate 的论点

“with_std=False or True”和“with_mean=False or True”之间的 StandardScaler 区别

graphQL 启动报错No method or field found with any of the following signatures (with or without one of [i

之间有什么http_basic_authenticate_with和authenticate_or_request_with_http_basic区别?

SQLAlchemy query with OR/AND/like common filters