如何跨两个SQL Server表检索审计跟踪并按正确的顺序将它们放回?
背景背景:
我有一个名为Project的数据库表和一个名为ProjectHistory的表,具有相同的模式。我正在使用nhibernate所以我还有一个名为Project的域对象和一个名为ProjectHistory的域对象(源自Project)。
目标
我的目标是检索这些表中的数据并按照发生的事件将它们按顺序放回,并让C#代码输出最后n次更改的典型审计跟踪屏幕
细节
两个表都具有以下字段和数据类型
Id - (int) - Project中的主键,注意:历史表中没有PK
LastUpdated(日期时间)
名称(varchar)
描述(varchar)
时间戳(时间戳)
Projecthistory表的目标是每当我对Project表进行更新时,ProjectHistory表都会插入一个带有旧记录的新行,这样我就可以拥有完整的审计跟踪。
我通过使用此触发器实现此目的:
ALTER TRIGGER ProjectTrigger
ON Project
AFTER UPDATE
AS
SET NOCOUNT ON
insert into ProjectHistory
select * from deleted
我的问题是,我现在需要一些C#代码来汇总审计历史记录,其中用户选择最近n个事件。
例:
以下是事件的示例:
1月10日 - 创建项目1(历史上还没有)
1月11日 - 创建项目2
在1月15日 - 编辑项目2(将项目2的历史表中的条目与1月11日的日期更新为)
1月25日 - 编辑项目1(将项目1的历史表中的条目放在1月10日的日期)
所以,正如你可以看到我是否按历史表中的lastupdated字段降序排序,它将事件4的结果放在事件3的结果之前,这是乱序的。
码
我尝试了以下代码尝试将它们放在一起,但我将解释下面的缺陷:
public IEnumerable<Project> GetHistory<Project, ProjectHistory>(int numberOfChanges)
{
IEnumerable<Project> current;
IEnumerable<Project> history;
current = Session.Query<Project>()
.OrderByDescending(r => r.LastUpdated)
.Take(numberOfChanges);
history = Session.Query<ProjectHistory>()
.OrderByDescending(r => r.LastUpdated).Cast<Project>();
IEnumerable<Project> all = current.Concat(history);
return all.OrderByDescending(r => r.Id).ThenByDescending(r => r.LastUpdated);
}
}
我上面代码的主要问题是:
历史记录上的LastUpdated时间将反映上一个Project更新的LastUpdated时间,因此我无法对历史表中该字段的desc进行排序,并假设我将获得正确的事件降序。
我可以使用timestamp字段进行排序(因为这是输入记录的实际时间),但似乎你不能使用C#nhibernate对该字段进行排序,因为该字段只是一个二进制(8)所以它翻译到C#中的byte [],它不支持IComparable。
我可以在Project表上使用lastUpdated字段,因为按lastupdate字段排序将按顺序获取最新的最新事件。我想到只循环项目表,然后为每个项目执行单独的查询以获取最新的历史项目,但是这不支持对同一项目ID进行多次更改的情况。问题是我无法找到以正确顺序获取数据的方法。
我的主要观点是,我想完成我认为必须要解决的非常通用的事情,所以我必须在这里错过基本模式。
我已经有了可以将一个Project对象与另一个项目对象进行比较并返回字段差异的代码(这完美无缺)但我只需要一个建议来确定如何以正确的顺序从这些表中的数据库中获取这些数据(从我的查询或事后的代码)所以我可以显示“最后n个更改”,然后使用我的逻辑显示每个更改的字段差异。
没有找到相关结果
已邀请:
3 个回复
坝硷操
藐刚
甲车劲