我使用Entity Framework作为数据存储编程WPF C#应用程序。数据库对外部更改是开放的,即用户可以在我的应用程序之外登录数据库并编辑,例如,特定实体的名称。我希望保持此功能,因为它允许用户轻松导入来自不同来源的数据。但是,我想告知用户是否对特定实体进行了此类更改。
为实现这一目标,我实施了哈希策略。在每次保存时,应用程序将计算实体的MD5哈希值。在加载时,它将根据此哈希验证实体,以确保不进行任何外部更改。我使用以下示例实现散列策略,该示例使用了BinaryFormatter类:http://www.codeproject.com/Articles/21312/Generating-MD-Hash-out-of-C-Objects
我遇到的是,实体没有返回相同的哈希值(即使没有外部更改)。这是由于" _entitywrapper"属性也被序列化,其中" _entitywrapper"在跟踪实体时,EF会自动添加到每个实体吗?
如果情况确实如此,我应该使用不同的序列化方法,还是完全不同的方法?
答案 0 :(得分:1)
当然,BinaryFormatter
不是最佳方式。无论是绩效观还是可用性。
如果您想要一个快速,易于编写的二进制序列化器,则应使用协议缓冲区。 C#有两种实现方式。
您可以在Nuget上找到它们。
但是,如果您打开以更改方法,为什么不使用设置为上次修改的时间戳或版本ID?
Datetime
字段,每次修改时设置为Datetime.UtcNow
。如果一个对象的时间戳比你上一次加载的时间更新,那么它同时被修改了。
注意:它与并发中使用的时间戳无关。 <强>优点:强>
- 易于理解并向同事解释。
的缺点:强>
- 需要在每个实体中实施。需要在表格中添加一列。如果经常调用,Datetime.UtcNow
可能会很昂贵。
int
或long
字段,每次修改实体时都会增加该字段。如果对象的版本ID大于它的上一个版本ID,则同时修改它。它与timestamp方法没有太大区别,但它更高效,并且使用更少的数据库内存。