我的域中有一个名为“服务”的实体。为了简单起见,我们假设它只有两个值对象:
服务ID(uuid) 客户端ID(uuid)
我可以通过其自己的存储库(“ServiceRepository”)访问该实体。
我的应用程序需要从外部源导入服务,但外部源中的字段需要进行一些转换,然后才能使用“ServiceRepository”保存它们。我从外部源收到这两个字段:
外部服务Id (int) 客户端代码(字符串)
在保存这些外部服务之前,我需要生成 ServiceId 并找到 ClientCode 的 ClientId。
所以,我的方法如下:
我的问题是这是否是最好的方法,因为我将复制实体“服务”和存储库。有什么选择可以避免这种重复吗?
这是一个假设,但听起来
code
是客户端的自然键,而id
是RDBMS中用作主键的代理键。这同样适用于 ExternalClientId
与 ClientId
。如果确实如此,您应该考虑从域层隐藏 id,因为它特定于您正在使用的基础设施层。如果您想更改持久化模式,或者迁移到 NoSQL 数据库,将 id 发布到域层将是一个问题,因为它们是 RDBMS 和模式依赖的概念。
如果您只将自然键发布到领域层,存储库将为您进行翻译,并且实现非常简单:
namespace Domain.ServiceContext;
public class Service
{
public int ExternalServiceId { get; init; }
public string ClientCode { get; init; }
// additional service properties
}
namespace Domain.ServiceContext;
public interface IServiceRepository
{
void Import(Domain.ServiceContext.Service service);
}
namespace Infrastructure;
public class ServiceRepository : IServiceRepository
{
private readonly AppDbContext database;
/// <summary>
/// Returns the client id from the code or throws exception if not found
/// </summary>
private Guid FindClientId(string code) => database.Clients
.First(client => client.Code == code)
.Select(client => client.Id);
/// <summary>
/// Insert a new service and maps the client code to id
/// </summary>
public void Import(Domain.ServiceContext.Service service)
{
database.Services.Add(new Infrastructure.Model.Service
{
ServiceId = Guid.NewGuid(),
ClientId = FindClientId(service.ClientCode)
ExternalServiceId = service.ExternalServiceId,
// map additional properties if needed
});
database.SaveChanges(); // INSERT statement
}
}