3

我们使用 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 db 集合。

4

1 回答 1

1

It seems like this is actually a question about mapping data from one object to another? If so, you may want to consider using something like Ditto or AutoMapper. I am the developer of ditto and have used it for a number of CQRS systems effectively...I wrote it to handle mixing in alot of different objects' data into the same View Model. These are known as OO mappers and typically have some form of bootstrapping configuration code, often using sensible conventions to avoid all the redundancy.

于 2012-10-09T01:53:51.077 回答