许多关系的历史表

时间:2013-09-24 17:18:37

标签: sql-server database entity-framework database-design many-to-many

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

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

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

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

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

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

问题来自多对多的映射表。我可以为映射表做同样的事情,并有一个历史表,但我需要能够说“在修订版3中,这个EntityA的列有这些值,以及这些与EntityB的关系”。 EntityA历史表可以通过ChangeId与映射历史表连接,但是当只更改EntityA的名称时会发生什么?在那时,关系历史将会丢失,因为它是一个新版本。

我可以想到需要支持的三种情况:

  1. 只更改了EntityA,关系没有变化。
  2. 只有EntityA和EntityB之间的关系发生变化。
  3. 两个EntityA都已更改,其关系已修改。
  4. 对于所有这些,需要保持一致性,并且我应该始终能够获得给定EntityA修订版的所有属性和所有关系。

    你知道如何处理多对多的牌桌吗?经过大量的搜索后,我找不到满意的解决方案。顺便说一下,我正在使用Entity Framework和SQL Server,以防万一。相似。

    由于

1 个答案:

答案 0 :(得分:0)

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

案例#1只更改了EntityA,关系没有变化。

  • 将EntityA的副本插入EntityAHistory(具有实际日期)
  • 将EntityAToEntityBMapping的副本插入到EntityAToEntityBMappingAHistory中(包含实际日期)
  • EntityA已更改并获得新版本

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

  • 将EntityAToEntityBMapping的副本插入到EntityAToEntityBMappingAHistory中(包含实际日期)
  • EntityAToEntityBMapping已更改并获得新版本

案例#3 EntityA都已更改并且其关系已修改。

  • 将EntityA的副本插入EntityAHistory(具有实际日期)
  • 将EntityAToEntityBMapping的副本插入到EntityAToEntityBMappingAHistory中(包含实际日期)
  • EntityA已更改并获得新版本
  • EntityAToEntityBMapping已更改并获得新版本

(实际上案例#1和案例#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
相关问题