Entity framework 使用ORM管理实体及其快照

Entity framework 使用ORM管理实体及其快照,entity-framework,design-patterns,ef-code-first,domain-driven-design,Entity Framework,Design Patterns,Ef Code First,Domain Driven Design,我想使用Jimmy Nilsson在他的书中提到的一个想法,那就是如果我有一个像产品这样的实体,我想拍一张该实体的快照以获取历史信息,比如产品快照,但我想知道如何用ORM实现这一点(我目前正在使用实体框架)。我面临的主要问题是,如果我有另一个实体,如OrderLine,通过其构造函数接收产品,那么实体框架将需要您创建一个您希望保留的类型的公共属性,因此这将迫使我拥有类似以下内容: class OrderLine { public Product Original Product {get; se

我想使用Jimmy Nilsson在他的书中提到的一个想法,那就是如果我有一个像产品这样的实体,我想拍一张该实体的快照以获取历史信息,比如产品快照,但我想知道如何用ORM实现这一点(我目前正在使用实体框架)。我面临的主要问题是,如果我有另一个实体,如OrderLine,通过其构造函数接收产品,那么实体框架将需要您创建一个您希望保留的类型的公共属性,因此这将迫使我拥有类似以下内容:

class OrderLine {
public Product Original Product {get; set;}
public ProductSnapshot Snapshot {get; set;}
}

这看起来很尴尬,也不直观,我不知道如何正确处理数据绑定(我应该绑定到哪个属性)最后,我认为产品是一个实体,而产品快照是一个价值对象,而且只有在接受订单行之后,才需要拍摄快照。

为什么订单行必须有ProductSnapshot属性?我想,如果需要获取历史信息,您可以从Product类中获得ProductSnapshot的链接,或者,如果您只是想在某些情况下保存产品状态,只需在Product partial类中实现一个SaveSnapshot方法,或者为其提供一个扩展方法。

在执行DDD时,请忘记数据库e存在。这意味着ORM也不存在。现在,因为您不必关心持久性和ORM限制,您可以根据域需要对ProductSnapshot进行建模

创建一个包含所有必需成员的ProductSnapshot类。该类可能是SnapshotService.GetSnapshot(产品p)的结果。拥有ProductSnapshot后,只需将其发送到存储库SnapshotRepository.Save(快照)。作为快照,这意味着它可能更像一个数据结构,一个“哑”对象。它也应该是不变的“冻结”

存储库将使用EF来实际保存数据。您可以决定EF实体和关系是什么。ProductSnapshot被持久性视为一个业务对象(实际上它只是一个简单的Dto并不重要),EF实体看起来可能非常不同(例如,我将业务对象以序列化形式存储在键值表中)根据您的查询需要

定义EF实体后,需要将ProductSnapshot映射到它们。ProductSnapshot本身很可能可以用作EF实体,因此不需要进行任何映射


关键是,拍摄快照似乎是一种域行为。只有在拥有快照后,才能处理EF,并且与处理任何其他业务对象时完全一样。

您如何看待绑定问题,因为如果我只有ProductSnapshot类型的属性,那么该属性将为null,直到订单行被确认为止med,如果我有一个Product类型的属性,但情况正好相反,也会发生同样的情况?我想你误解了我。产品快照是一个业务对象,将由存储库保存。OrderLine类可能包含一个产品快照,但这不是EF问题。存储库应该知道如何组装订单行无论是否有产品或快照。存储库使用EF获取相关数据,然后将所有内容放在一起。简而言之,在建模业务对象时,保持域和持久层分开,不要混合使用ORM。ORM帮助您更轻松地处理数据库,但存储库负责处理业务对象s、 你必须决定这里的订单线、产品和产品快照是业务对象还是EF实体,我希望它们不用于对域进行建模。我明白你关于存储库的观点,我觉得这将引发一场长时间的讨论,不,我不使用EF实体对域进行建模,但我觉得你会一直这样做你必须考虑一下你正在使用的持久性框架。谢谢你的帮助