业务问题与持久性问题

Posted

技术标签:

【中文标题】业务问题与持久性问题【英文标题】:Business concerns vs persistence concerns 【发布时间】:2014-03-08 20:04:42 【问题描述】:

我正在使用实体框架来处理我的核心模型和数据库之间的持久性。我看不到一种在不损害我的域实体以实现持久性的情况下令人满意地使用 EF 的方法。我真的很想实现一个富领域模型,它真的不知道它的状态是如何存储的。

例如,EF 约定是将多个关系映射到虚拟 ICollections。我意识到我可以使成员受到保护,但如果核心模型和 EntityTypeConfigurations 位于不同的程序集中,这将不起作用。

我宁愿通过保护它的关联成员来保护我的模型不进入无效状态,更喜欢以下...

public class MyEntity 

    private ICollection<Thing> myThings  get; set; 

    public ReadOnlyCollection<Thing> MyThings  get  return myThings.AsReadOnly();  

    public void AddThing(Thing toAdd)  // validate, etc 


我已经确定的可能解决方案(没有一个是我真正满意的)...

    映射到 DTO,并让域实体包装它的附属 DTO,因此 DTO 有数据,实体有行为。

    将 EntityTypeConfigurations 移入核心程序集。

    让 Core 和 Infrastructure.Data.Ef 项目成为“朋友”并使用内部访问修饰符(我真的很讨厌这个想法)。

    接受限制。让集合公开变异,并在持久化之前执行一些其他验证。

    忘记 EF 并返回 ADO,NET。

还有其他想法吗?执着无知是无法实现的目标吗?

谢谢!

【问题讨论】:

您使用的是存储库模式吗? 您的域实体可以是您的 EF 实体,而无需在核心层中引用 EF 或处理内部访问修饰符,看看here 【参考方案1】:

在尝试击败 EF 并失败后,我更喜欢的解决方案是:

    创建您的域实体,完全不了解持久性。

    在您的存储库中,在内部使用 EF 实体,但将这些实体映射到/从您的域实体映射。您的存储库应该只接受和返回域实体。

    使用从 DB 自动生成,而不是 Code First,除非维护 2 组实体可以带来很大的好处。通常我觉得不值得。

正如我所说,这当然会在膝盖处切断 ORM。您不会得到延迟加载,但延迟加载在 DDD 中通常不能很好地工作,因为您必须在整个应用程序中一直公开您的数据库设计。

您的 ORM (EF) 将对您的应用完全隐藏,只有数据层中的存储库会与它进行内部处理。

【讨论】:

【参考方案2】:

我的建议:远离 Fluent Mapping,使用 XML。使用 .edmx 文件,您甚至可以轻松*映射私有属性。

除了它的语法非常冗长。

【讨论】:

以上是关于业务问题与持久性问题的主要内容,如果未能解决你的问题,请参考以下文章

数据库事务与特性

MySQL事务

MySQL—— 事务 (特性 与 并发编程带来的问题)

数据库四大特性;

spring 事务

030. sql事务特性