3

我需要跟踪几个实体的版本历史,以便能够查看其历史中任何给定点的所有属性的状态,包括它们的多对多关系。它还必须支持变更集。给定下表:

EntityA
-------
Id
Name
Revision
ChangeId

EntityB
-------
Id
Name
Revision
ChangeId

EntityAToEntityBMapping
-----------------------
EntityAId
EntityBId
ChangeId

ChangeTracking
--------------
ChangeId
Date
User
Description

对于 EntityA 和 EntityB 表,我将有一个包含完全相同列的历史表。数据始终通过对象模型进行修改,因此在提交任何更改之前,我将创建一个新的 ChangeTracking 条目并将其 Id 添加到任何正在插入或更新的实体中,并增加 Revision。然后我在 EntityA 和 EntityB 表上有一个插入/更新触发器,并将以前的数据复制到历史表中。在任何给定点,您都在其历史记录表中拥有实体的所有历史记录。

问题来自多对多映射表。我可以对映射表执行相同的操作并拥有一个历史表,但我需要能够说“在修订版 3 中,此 EntityA 的列具有这些值,以及与 EntityB 的这些关系”。EntityA 的历史表可以通过 ChangeId 与映射的历史表连接,但是如果只改变 EntityA 的名称会发生​​什么?那时,关系历史将丢失,因为它是一个新的修订版。

我可以想到三个需要支持的场景:

  1. 只有 EntityA 发生了变化,关系没有变化。
  2. 只有 EntityA 和 EntityB 之间的关系发生变化。
  3. EntityA 都已更改,其关系也已修改。

对于所有这些,需要保持一致性,并且我应该始终能够获取给定 EntityA 修订版的所有属性和所有关系。

你知道我如何处理多对多表的历史吗?经过大量搜索后,我无法找到令人满意的解决此问题的方法。顺便说一句,我正在使用实体框架和 SQL Server 以防万一。

谢谢

4

1 回答 1

0

这与您的想法有些不同,并且更简单,如果它支持您的所有需求场景,则可能不是问题。我希望我没有错过任何一个。

案例 #1 只有 EntityA 发生了变化,关系没有变化。

  • EntityA 的副本被插入到 EntityAHistory 中(带有实际日期)
  • EntityAToEntityBMapping 的副本被插入到 EntityAToEntityBMappingAHistory 中(带有实际日期)
  • EntityA 已更改并获得新修订版

案例 #2 只有 EntityA 和 EntityB 之间的关系发生了变化。

  • EntityAToEntityBMapping 的副本被插入到 EntityAToEntityBMappingAHistory 中(带有实际日期)
  • EntityAToEntityBMapping 已更改并获得新修订版

案例#3 EntityA 都被改变了,它的关系也被修改了。

  • EntityA 的副本被插入到 EntityAHistory 中(带有实际日期)
  • EntityAToEntityBMapping 的副本被插入到 EntityAToEntityBMappingAHistory 中(带有实际日期)
  • EntityA 已更改并获得新修订版
  • EntityAToEntityBMapping 已更改并获得新修订版

(其实case#1和case#2是可以合并的,只是把EntityAToEntityBMapping复制到EntityAToEntityBMappingAHistory中两次是多余的)

当您加入任何 EntityAHistory、EntityBHistory、EntityAToEntityBMappingHistory 时,
您不仅要在联接中包括 Id,还要包括 Revision 字段。例如,您想查看 EntityA 某个版本的历史记录:

select * 
from EntityAHistory A, EntityBHistory B, EntityAToEntityBMappingHistory M
where A.Id = EntityAToEntityBMappingHistory.EntityAId
and B.Id = EntityAToEntityBMappingHistory.EntityBId
and A.Revision = EntityAToEntityBMappingHistory.EntityARevision
and B.Revision = EntityAToEntityBMappingHistory.EntityBRevision
and A.Revision = :CertainRevisionOfEntityA

该模型:

EntityA
-------
Id
Name
Revision

EntityB
-------
Id
Name
Revision

EntityAToEntityBMapping
-----------------------
EntityAId
EntityBId

EntityAHistory
-------
Id
Name
Revision
Date

EntityBHistory
-------
Id
Name
Revision
Date

EntityAToEntityBMappingHistory
-----------------------
EntityAId
EntityARevision
EntityBId
EntityBRevision
Date
于 2013-09-24T17:53:01.933 回答