MapsterMapper / MapsterMapper/Mapster

Regression in v10 - Forced Update of Required Property [MapToTarget]

Open
#899 2 comments 0 reactions 0 assignees View on GitHub

A pull request for this has already been merged.

  • #902 by @DocSvartz — merged
bug
Dominant language
C#
Stars
5.2k
Forks
410
Avg merge
2d 12h
Merged PRs (30d)
6

Description

The following UpdateRoleAsync method works just fine with Mapster 7.4 but when I updated to Mapster 10 I am getting Reference constraint violatation from EF core because Mapster is modifying every other propery to default value that are not present in the DTO. I have to roll back to Mapster 7.4 to save the app from huge breaking change. How to get the old behavior back??


public record AuthorizableRoleRequest(string Name, bool IsActive);

public class AuthorizableRole : IAutoIncrementalEntity<long>
{
    public long Id { get; }
    public required string Name { get; set; }
    public required string NormalizedName { get; set; }
    public required bool IsActive { get; set; }
    public required long CreatedByUserId { get; init; }
    public required long? UpdatedByUserId { get; set; }
    public required DateTime CreatedAtUtc { get; init; }
    public required DateTime? UpdatedAtUtc { get; set; }
}

public async Task<ValueOutcome<Successful, IBadOutcome<HttpBadOutcomeTag>>> UpdateRoleAsync(
    long roleId, AuthorizableRoleRequest request, UserId userId, CancellationToken ct)
{
    var entity = await _appDbContext
        .AuthorizableRoles
        .FirstOrDefaultAsync(x => x.Id == roleId, ct);

    if (entity is null)
    {
        return new HttpBadOutcome(HttpBadOutcomeTag.NotFound);
    }

    var normalizedName = request.Name.ToUpperInvariant();

    var exists = await _appDbContext
        .AuthorizableRoles
        .AnyAsync(x => x.Id != entity.Id && x.NormalizedName == normalizedName, ct);

    if (exists)
    {
        return new HttpBadOutcome(HttpBadOutcomeTag.Conflict);
    }

    await request.BuildAdapter().AdaptToAsync(entity);
    
    entity.NormalizedName = normalizedName;
    entity.RefreshUpdateTrackingData(userId, _dateTimeProvider.UtcNow);

    _appDbContext
        .AuthorizableRoles
        .Update(entity);

    await _appDbContext.SaveChangesAsync();

    return new Successful();
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the UpdateRoleAsync example and compare AdaptToAsync behavior between Mapster 7.4 and 10, focusing on properties omitted from AuthorizableRoleRequest. Done means omitted entity properties retain their existing values so the EF Core update no longer violates reference constraints; a linked pull request is already closed and merged.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
backend, database
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.