在開發中經常會遇到管理數據變化的需求。例如:績效系統需要根據季度開始時某人的上級領導來確定由誰來打績效分,遊戲系統根據活動結束時間的積分發放獎勵…… 如果數據庫中只存了最新的狀態,就無法實現這樣的功能了。
這時就需要我們製作一套“事件溯源”系統。當然,我們這次實現的“事件溯源”並不是真正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 = "[email protected]"
};
userRepository.AddOrEdit(model, new DateTime(2019, 8, 20, 15, 30, 20));
model.Mail = "[email protected]";
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