领域驱动设计聚合根Demo实体:
public class Demo : FullCompanyEntity<int>, IAggregateRoot
{
public string? FirstName { get; private set; }
public string LastName { get; private set; }
public string? FullName { get; private set; }
public string? Phone { get; private set; }
public string? Email { get; private set; }
public int? LeadId { get; private set; }
public int? SaleId { get; private set; }
public DateTime StartedAt { get; private init; }
public DateTime? EndedAt { get; private set; }
public int? TotalSpentTime { get; private set; }
public double Latitude { get; private set; } // float8 psg type
public double Longitude { get; private set; }// float8 psg type
public Address? Address { get; private set; }
public bool IsLive { get; private set; }
private Demo() { } // for ef
public Demo(double latitude,
double longitude,
string lastName,
in int companyId,
in int importerId,
in int organisationId,
in int distributorId,
Address? address = null,
string? firstName = null,
string? phone = null,
string? email = null,
int? leadId = null) : base(companyId, importerId, organisationId, distributorId)
{
Guard.Against.LatitudeFormat(latitude);
Guard.Against.LongitudeFormat(longitude);
Latitude = latitude;
Longitude = longitude;
Address = address;
FirstName = firstName;
LastName = lastName;
FullName = firstName.FullName(lastName);
Phone = phone;
Email = email;
LeadId = leadId;
StartedAt = DateTime.UtcNow;
IsLive = true;
}
}
请求Dto:
public class RequestDemoDto
{
public string? FirstName { get; private set; }
public string LastName { get; private set; }
public string? Phone { get; private set; }
public string? Email { get; private set; }
public int? LeadId { get; private set; }
public int? SaleId { get; private set; }
public double Latitude { get; private set; }
public double Longitude { get; private set; }
public AddressDto? Address { get; private set; }
}
我上面分享了两个类,一个是领域实体,另一个是request dto,它将用于API接收请求。
这里我想到了几个问题。在问他们之前,我想先解释一下实体ctor的目的。
演示实体不得在没有必需属性的情况下初始化(必需的属性纬度、经度、姓氏、公司 ID、导入者 ID、组织 ID、分销商 ID)
即使演示实体不需要某些属性,用户(通过 dto 请求 Web API 的用户)也可以在第一次初始化时设置它们 等等。名字、电话、电子邮件、leadId
但是,我创建了这样一个ctor,以便在上面的ctor中提供我想要的功能,但这里出现了类似的问题。
当从 dto 映射到 demo 或简单地将参数传递给 ctor 时,如下所示;
var demo = new Demo(demoDto.Latitude, demoDto.Longitude, demoDto.LastName, companyId, importerId, organisationId, distributorId, firstName: demoDto.FirstName, phone: demoDto.Phone, email: demoDto.Email, leadId: demoDto.LeadId);
数据出现一些问题。例如,如果phone或firstname是空字符串,那么它们在数据库中不会被记录为null。 或者如果leadId默认为0,则数据库leadid将为0而不是null。但我希望它为空。但如上所示,用户设置的内容仍然 由于运行时不知道它的作用,因此我需要在从 dto 映射实体时将所有 dto 属性切换到 ctor。
这种情况我该怎么办,我应该设计什么样的ctor或者dto的实体映射应该是什么样的?
注意: 如果数据库中未设置任何值,则名字、电话、电子邮件、LeadId、SaleId、Address 必须为空。
注意: 在数据库中保留 null 是一个不好的方法吗?您也可以评论这个问题。
感谢任何能帮忙或不能帮忙的人。
您可以创建一个仅包含所需值的构造函数
public Demo(double latitude,
double longitude,
string lastName,
in int companyId,
in int importerId,
in int organisationId,
in int distributorId) : base(companyId, importerId, organisationId, distributorId)
{
Guard.Against.LatitudeFormat(latitude);
Guard.Against.LongitudeFormat(longitude);
Latitude = latitude;
Longitude = longitude;
LastName = lastName;
StartedAt = DateTime.UtcNow;
IsLive = true;
}
更改非必需属性以允许公共设置
public string? FirstName { get; set; }
public string? Phone { get; set; }
public string? Email { get; set; }
public int? LeadId { get; set; }
public Address? Address { get; set; }
然后你可以做如下的事情
var demo = new Demo(demoDto.Latitude, demoDto.Longitude, demoDto.LastName, companyId, importerId, organisationId, distributorId)
{
FirstName = !string.IsNuulOrEmpty(demoDto.FirstName) ? demoDto.FirstName : null,
Phone = !string.IsNuulOrEmpty(demoDto.Phone) ? demoDto.Phone : null,
Email = !string.IsNuulOrEmpty(demoDto.Email) ? demoDto.Email : null,
LeadId = demoDto.LeadID > 0 ? demoDto.LeadID : null
};
您可能还想执行以下操作:
private string? _firstName;
public string? FirstName
{
get
{
return _firstName;
}
set
{
_firstName = value;
if (!string.IsNullOrEmpty(_firstName))
{
FullName = _firstName.FullName(LastName);
}
}
}
您似乎没有对 Address 做任何事情 - 看起来您需要使 dto 适应 Address 类型或在设置它时适当地构造它,但这应该遵循类似的模式。