C# DDD 与 EF Core 使用相同的域实体/聚合来映射表或单独的类

问题描述 投票:0回答:1

我不知道这 2 个选项中哪个最合适。

方案一:使用aggregateroot或者entity(聚合子实体)来映射表。

public class User : AggregateRoot 
{
    string Name { get; }
    string Email { get; }

    // Logic ...
}

现在配置 EF Core 实体:

public class EntityTypeConfiguration : IEntityTypeConfiguration<User> 
{
    public void Configure(EntityTypeBuilder<User> builder) 
    {
        // ... map props.
    }
}

选项 2:复制代码并创建 2 个具有自己作用域的类。

public class User : AggregateRoot 
{
    string Name { get; }
    string Email { get; }

    // Logic ...
}

public class UserTable 
{
    Guid Id { get; }
    string Name { get; }
    string Email { get; }

    // No logic here ...
}
public class EntityTypeConfiguration : IEntityTypeConfiguration<UserTable> 
{
    public void Configure(EntityTypeBuilder<UserTable> builder) 
    {
        // ... map props.
    }
}

使用第二个选项,我可以将我的实体保存在同一个文件夹中,例如

EFCoreEntities
,代码应该更干净,但有很多重复的代码。

使用第二种方法,我必须在

UserTable
User
之间编写额外的映射器(也许使用mapster / automapper)

例如,这将是

IUserRepository
,方法为:

// Here parameter is an User but have to map into UserTable
Add(User user) 
{
    var entity = user.MapToUserTable();
    dbContext.Users.Add(entity)
    // ...
}

您使用哪个选项,有什么优点和缺点?

c# entity-framework-core domain-driven-design webapi ddd-repositories
1个回答
0
投票

我使用选项 2 单独的实体和域开发了一个相对较大的系统。

选项 2 的好处 ✅:

  • 域不限于数据库模式。
    • 但是,我们从未遇到过域偏离模式的情况。一直都是1对1。这意味着映射变成了额外的“间接”,而预期的偏差从未发生。

选项 2 缺点🔻:

  • 大量的映射代码很快就会变得复杂。
  • 没有实际好处的额外层。映射始终是一对一的。这意味着映射变成了额外的“间接”,而预期的偏差从未发生。
    • 我发现额外的层使导航变得更加困难。

话虽如此。我会选择选项 1,但有一个警告(继续阅读)

我认为选项 1 的唯一缺点是一对多导航属性。例如,如果您使用集合导航属性的引用进行验证,并且忘记加载它们,则您的验证将默默失败,因为无法从域端知道您的实体已加载或未加载。这增加了域和持久性代码之间的耦合程度,并且域不应该关心持久性。

解决方案是

  1. 适应延迟加载
  2. IEntityTypeConfiguration
    启用自动加载。

请记住,如果您决定启用延迟加载,请在任何“1-N 选择问题”发生时立即捕获它们。设置性能监控、集成和负载测试

© www.soinside.com 2019 - 2024. All rights reserved.