c# - DDD : entities mapped to tables with lots of databse columns

标签 c# domain-driven-design entities

我正在尝试按照 DDD 方法构建实体,其中属性具有私有(private) setter 和公共(public) getter,并且赋值是通过构造函数完成的。这种方法的问题似乎是当您访问一个包含很多列的表时,我们有一个至少有 40 列的表。它很快变成了一场噩梦。我发现一些文章似乎指向 Fluent Interface 或 Factory Pattern。看起来像 40 列,但即使使用这些模式,清洁器仍然可能失控。这些列与表设计相关并且不违反 SRP。此外,在尝试维护表大小并可能根据逻辑分组将实体分解为更小的值对象时,看起来某些值对象仍然会很大。有人可以指出如何在不破坏 DDD 的情况下处理这种情况的正确方向吗?

最佳答案

并不是说 DDD 不适合宽列。 隐藏 setter 也不是 DDD 的特定要求,而是普通的旧封装。 (保护您的数据的修改。) 如果您必须设置很多这样的值,并且您发现自己混淆了代码,那么可以像您提到的那样,将构造移至工厂。

秘诀当然是不要让任何消费代码在不遵循正确的“域逻辑”的情况下将任何值分配给您的域对象,因此隐藏了 setter 。 当然,有时您必须将所有这些值设置为您的域对象,并且这些值来自某些 dto 或 mvc 模型或其他东西,然后使用可以映射/分配值的 Mapper 类是保持消费代码清洁的好方法.

您甚至可以考虑使用 Jimmy Bogard 的 AutoMapper 之类的东西:http://automapper.org/顺便说一句,将值分配给私有(private) setter 也没有问题。

如果您使用 ORM 加载数据,其中一些支持私有(private) setter 和/或支持字段。 例如 NHibernate 允许在你的映射文件中这样做:

this.Property(x => x.Description, mapper => mapper.Access(Accessor.Field))

根据我的评论,使用类似 AutoMapper 的东西来减轻大量映射代码的编写。 将实现包装在如下所示的可注入(inject)类中,这将允许您在将来替换实现而无需执行霰弹枪手术。

public class ViewMapper<TModel, TDomain> : IViewMapper<TModel, TDomain>
{
    public TDomain MapToDomain(TModel dataItem)
    {
        return Mapper.Map<TModel, TDomain>(dataItem);
    }

    public List<TDomain> MapToDomain(IEnumerable<TModel> dataItems)
    {
        return dataItems.Select(this.MapToDomain).ToList();
    }

    public TModel MapToData(TDomain domainItem)
    {
        return Mapper.Map<TDomain, TModel>(domainItem);
    }

    public void MapToOriginalData(TDomain domainItem, TModel dataItem)
    {
        Mapper.Map(domainItem, dataItem);
    }

    public List<TModel> MapToData(IEnumerable<TDomain> domainItems)
    {
        return domainItems.Select(this.MapToData).ToList();
    }
}

AutoMapper 是高度可配置的,应该能够处理大多数情况。 设置一个映射器配置文件,您可以在其中准确地告诉它在映射期间要做什么:

public class ViewItemProfile : AutoMapper.Profile
{
    protected override void Configure()
    {
        Mapper.CreateMap<Domain, View>()
            .ForMember(x => x.ErrorRequestId, y => y.MapFrom(z => z.ErrorTypeId))
            .ForMember(x => x.Irrelevant, y => y.Ignore());
    }
}

关于c# - DDD : entities mapped to tables with lots of databse columns,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28544449/

相关文章:

c# - 在 StackExchange.Redis 中将对象转换为 HashEntry

c# - 在 C# 程序中使用 C++ 常量

c# - 与 C# 相比,VB.NET 是弱类型的吗

c# - 如何在 DDD 和存储库模式中对此建模

json - Twitter 流媒体 API - 如何阅读转推

c# - 从 checkbox_CheckChanged 返回一个值

domain-driven-design - 微服务和服务组合中的规范化或非规范化数据

ruby-on-rails - 在 CQRS 和 DDD 流程中创建值对象的位置

android - 房间 : related entities - usable public constructor

c# - Entity Framework v4 -> 需要一些关于 POCO 和实体的帮助