我们使用 MongoDb 作为我们应用程序的数据源,该应用程序是使用 cqrs 和事件源构建的。我们今天面临的问题是什么是实现事件映射(非规范化)以读取数据库的最佳方式。例如,我们有一个用户 MongoDb 集合,其中包含有关用户的所有信息。我们有这样的事件:
[Serializable]
public class PasswordChangedEvent : DomainEvent
{
private string _hashedPassword;
private string _salt;
public PasswordChangedEvent()
{
}
public PasswordChangedEvent(string hashedPassword, string salt, DateTime createdDate)
:base(createdDate)
{
HashedPassword = hashedPassword;
Salt = salt;
}
public string HashedPassword
{
private set { _hashedPassword = value; }
get { return _hashedPassword; }
}
public string Salt
{
private set { _salt = value; }
get { return _salt; }
}
}
像这样阅读 DTO
public class User : BaseReportDataObject
{
public string Name { get; set; }
public string Email { get; set; }
public string Gender { get; set; }
public DateTime? BirthDate { get; set; }
public string HashedPassword { get; set; }
public string Salt { get; set; }
public string RestoreHash { get; set; }
public string OpenIdIdentifyer { get; set; }
}
我们当前使用事件更新文档的解决方案是这样的:我们有一些事件映射代码(BsonClassMap.RegisterClassMap 等)和更新代码:
MongoCollection.Update(Query<PasswordChangedEvent>.EQ(ev => ev.AggregateId, evnt.AggregateId),
Update<PasswordChangedEvent>
.Set(ev => ev.HashedPassword, evnt.HashedPassword)
.Set(ev => ev.Salt, evnt.Salt));
代码在我看来有点难看和多余:有了所有 lambda 的东西,我们仍然需要显式地提供属性值。另一种方法是将 PasswordChangedEvent 替换为 User dto,这样我们就不再需要事件映射了:
MongoCollection.Update(Query<ReadDto.User>.EQ(u => u.Id, evnt.AggregateId),
Update<ReadDto.User>.Set(u => u.HashedPassword, evnt.HashedPassword));
那么问题又来了:有没有更好的方法来做这种类型的映射?两种类型的对象(事件和 DTO)映射到同一个 mongo 数据库集合。
最佳答案
看来这其实是一个关于将数据从一个对象映射到另一个对象的问题? 如果是这样,您可能需要考虑使用类似 Ditto 的东西或 AutoMapper .我是 ditto 的开发者,并且已经将它有效地用于许多 CQRS 系统……我编写它是为了处理将大量不同对象的数据混合到同一个 View 模型中。 这些被称为 OO 映射器,通常具有某种形式的引导配置代码,通常使用合理的约定来避免所有冗余。
关于c# - MongoDb C# 驱动程序 : mapping events to read database in cqrs solution,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12708444/