【问题标题】:AutoMapper overriding EF Core auto-generated propertiesAutoMapper 覆盖 EF Core 自动生成的属性
【发布时间】:2022-01-20 12:29:39
【问题描述】:

我正在尝试在我的应用程序中使用时间戳来记录行的创建和上次修改时间。将 DTO 映射到实体时,属性被覆盖并在它们最初具有值时设置为 null。 (注意我使用 CQRS 来处理命令)

这是我的基础实体,每个 EF Core 实体都继承

public class BaseEntity : IBaseEntity, IDeletable
{
    public int Id { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTimeOffset? DateCreated { get; set; }

    public string CreatedBy { get; set; }
    public string LastModifiedBy { get; set; }
    public DateTimeOffset DateModified { get; set; } = DateTimeOffset.UtcNow;
    public bool IsDeleted { get; set; }
    public string DeletedBy { get; set; }
    public DateTimeOffset? DateDeleted { get; set; }

    [Timestamp]
    public byte[] RowVersion { get; set; }
}

用于请求的 DTO 是:

public sealed class UpdateCustomerCommand : IRequest<Result<int>>
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Phone { get; set; }
    public string Email { get; set; }
    public string PrimaryContact { get; set; }
    public string SecondaryContact { get; set; }
    public ICollection<AddressCreateDto> Addresses { get; set; }
}

请注意,我不包含 BaseEntity 中的属性,因为 EF Core 应该自动生成这些值,我认为在发出请求时,任何人都不需要担心名为 DateCreated 等的属性……它只是用于审核目的

var repository = _unitOfWork.GetRepository<Customer>();
var customer = await repository.FindAsync(request.Id, cancellationToken);
if (customer == null) throw new KeyNotFoundException();
var mappedCustomer = _mapper.Map<Customer>(request);
await repository.UpdateAsync(request.Id, mappedCustomer);

当我使用FindAsync(request.Id, cancellationToken) 方法检索对象时,值在那里,但在我执行映射后,它们被覆盖。

这是映射。

CreateMap<UpdateCustomerCommand, Customer>()
.ForMember(dst => dst.Addresses, opt => opt.MapFrom(src => src.Addresses))
.ReverseMap();

【问题讨论】:

    标签: c# .net-core entity-framework-core automapper


    【解决方案1】:

    如果您不想映射这些属性,则必须在创建映射时明确说明。根据您使用的 AutoMapper 版本,您需要忽略映射或使用 DoNotValidate。

    // Old
    cfg.CreateMap<Source, Dest>()
        .ForMember(dest => dest.DateModified, opt => opt.Ignore());
    
    // New
    cfg.CreateMap<Source, Dest>()
        .ForMember(dest => dest.DateModified, opt => opt.DoNotValidate());
    

    这是link to the documentation

    【讨论】:

    • 非常感谢。我现在就试试这个。
    • @Jacob 我更新了代码以反映目的地,因为我发布的代码中的示例最初使用了 ForSourceMember。希望这可以帮助您解决问题。
    • 确实如此,我使用的是旧的.Ignore() 方法。感谢您的帮助
    猜你喜欢
    • 2018-01-03
    • 2012-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多