在开发中经常会遇到管理数据变化的需求。例如:绩效系统需要根据季度开始时某人的上级领导来确定由谁来打绩效分,游戏系统根据活动结束时间的积分发放奖励…… 如果数据库中只存了最新的状态,就无法实现这样的功能了。
这时就需要我们制作一套“事件溯源”系统。当然,我们这次实现的“事件溯源”并不是真正DDD上的“事件溯源”,真正的事件溯源是以领域事件作为驱动实现的。我们的这个系统,叫“数据版本管理组件”更合适。现在我们就利用开源组件 VersionRepository 来实现这个功能。
VersionRepository 是一个以Mongodb 作为存储实现的数据版本管理组件,数据的比较、快照的生成对使用者都是透明的,使用起来比较简单。
准备工作:
一,安装一个 mongodb ,推荐使用 docker 方式,一个命令即可:docker run -p 27017:27017 -d mongo:3.2
二,建立一个 NetCore 2.2 的控制台项目,并安装 xLiAd.MongoEx.VersionRepository。
开始编码:
二,建立一个实体类,并继承 VersionEntityModel 。
public class UserModel : VersionEntityModel
{
[Key]
public string EmployeeCode { get; set; }
public string CName { get; set; }
public string Mail { get; set; }
public DateTime? BirthDay { get; set; }
public int Class { get; set; }
}
其中 Key 标记模型的实际意义上的主键(不可重复),如果没有,可不标。
三,编写如下代码在 Main 方法里
MongoUrl mongoUrl => new MongoUrl("mongodb://你的Mongo连接串");
VersionMongoRepository<UserModel> userRepository => new VersionMongoRepository<UserModel>(mongoUrl);
var model = new UserModel()
{
CName = "Jim Green",
EmployeeCode = "12345",
Mail = "jim@sina.com"
};
userRepository.AddOrEdit(model, new DateTime(2019, 8, 20, 15, 30, 20));
model.Mail = "john@sina.com";
model.CName = "John Smith";
userRepository.AddOrEdit(model, new DateTime(2019, 9, 20, 15, 30, 20));
var m0 = userRepository.GetModel("12345", new DateTime(2019, 8, 20));
var m1 = userRepository.GetModel("12345", new DateTime(2019, 8, 21));
var m2 = userRepository.GetModel("12345", new DateTime(2019, 9, 20));
var m3 = userRepository.GetModel("12345", new DateTime(2019, 9, 21));
var m4 = userRepository.GetModel("12345", DateTime.Now);
四,确认从m0 到 m4 是不是符合当时的状态。
m0 应该是 null ,因为实体在当时还没有建立;
m1 是 Jim Green ,因为实体已经第一次建立了。
m2 应该和 m1 是一样的,因为GetModel的时候在更新之前。
m3 应该是 John Smith ,因为已经修改了。
m4 应该和 m3 是一样的,除非你穿越了。
五,VersionMongoRepository 里提供了基本的增删改查功能,还可根据快照时间进行检索、分页。
如果你也有同样的需求,可以按照上述方法试一试;如果你想更多了解一下,可以到github 下载源码:https://github.com/zl33842901/MongoEx