簡體   English   中英

使用AutoMapper將DTO映射回模型

[英]Mapping DTO back to model with AutoMapper

我有一個Fixture模型:

public partial class Fixture
{
    public int FixtureId { get; set; }
    public string Season { get; set; }
    public byte Week { get; set; }

    //foreign key
    public int AwayTeamId { get; set; }
    //navigation properties
    public virtual Team AwayTeam { get; set; }

    //foreign key
    public int HomeTeamId { get; set; }
    //navigation properties
    public virtual Team HomeTeam { get; set; }

    public byte? AwayTeamScore { get; set; }
    public byte? HomeTeamScore { get; set; }
}

還有一個夾具DTO:

public class FixtureDTO
{
    public int Id { get; set; }
    public string Season { get; set; }
    public byte Week { get; set; }
    public string AwayTeamName { get; set; }
    public string HomeTeamName { get; set; }
    public byte? AwayTeamScore { get; set; }
    public byte? HomeTeamScore { get; set; }
}

我正在使用AutoMapper進行映射,這是我第一次嘗試使用它。 這是我的映射:

CreateMap<Fixture, FixtureDTO>()
            .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.FixtureId))
            .ForMember(dest => dest.AwayTeamName, opt => opt.MapFrom(src => src.AwayTeam.TeamName))
            .ForMember(dest => dest.HomeTeamName, opt => opt.MapFrom(src => src.HomeTeam.TeamName));
        CreateMap<FixtureDTO, Fixture>();

在使用Fixture並將其映射到我用來顯示數據的FixtureDTO時,它可以很好地工作。 但是,當我想更新數據並將FixtureDTO傳遞回以將其映射回Fixture時,出現錯誤。

public HttpResponseMessage PutFixture(int id, FixtureDTO fixture)
    {
        if (ModelState.IsValid && id == fixture.Id)
        {
            //do mapping manually here?

            var updated = _repository.UpdateFixture(Mapper.Map<Fixture>(fixture));
            return Request.CreateResponse(updated ? HttpStatusCode.OK : HttpStatusCode.NotFound);
        }
        return Request.CreateResponse(HttpStatusCode.BadRequest);
    }

這是我得到的錯誤:

Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

有人可以幫忙嗎?

編輯:反向映射:

CreateMap<Fixture, FixtureDTO>()
            .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.FixtureId))
            .ForMember(dest => dest.AwayTeamName, opt => opt.MapFrom(src => src.AwayTeam.TeamName))
            .ForMember(dest => dest.HomeTeamName, opt => opt.MapFrom(src => src.HomeTeam.TeamName));
        CreateMap<FixtureDTO, Fixture>()
            .ForMember(dest => dest.FixtureId, opt => opt.MapFrom(src => src.Id))
            .ForMember(dest => dest.AwayTeam.TeamName, opt => opt.MapFrom(src => src.AwayTeamName))
            .ForMember(dest => dest.HomeTeam.TeamName, opt => opt.MapFrom(src => src.HomeTeamName));

通常,當EF檢測到以下情況之一時,就會引發該異常:

樂觀並發沖突 :通常在修改您要編輯的實體時發生,否則會在您加載,編輯和保存該實體的時間進行修改。 (請參閱: 實體框架:“存儲更新,插入或刪除語句影響了意外的行數(0)。”

ID設置不正確 :未為Pks或FK 設置ID 當我錯誤地將Entity的FK設置為​​值並將關聯的對象設置為具有不同ID的對象時,我也看到了這樣的異常。

由於存儲庫中的某些代碼,很可能引發此異常。 如果將代碼發布到存儲庫中,我們可能會更好地了解導致異常的原因。

首先,您需要創建從DTO到實體的反向映射(如果需要,提供自定義成員映射):

Mapper.CreateMap<FixtureDTO, Fixture>();

其次-檢索,映射和更新現有實體

if (ModelState.IsValid && id == fixture.Id)
{
    Fixture entity = _repository.FindById(fixture.Id);
    Mapper.Map(fixture, entity); // Use this mapping method!
    var updated = _repository.UpdateFixture(entity);
    // etc
} 

@lazyberezovsky答案的擴展:

這是您可能需要的反向映射的一個(未經測試的)示例:

CreateMap<FixtureDTO, Fixture>()
        .ForMember(dest => dest.FixtureId,
                   opt => opt.MapFrom(src => src.Id))
        .ForMember(dest => dest.AwayTeam,
                   opt => opt.MapFrom(src => new Team
                                                 {
                                                     TeamName = src.AwayTeamName
                                                 }))
        .ForMember(dest => dest.HomeTeam,
                   opt => opt.MapFrom(src => new Team
                                                 {
                                                     TeamName = src.HomeTeamName
                                                 }));

我過去曾經使用過這種格式,並且效果很好,但也可以為團隊創建特定的映射。 例如:

CreateMap<string, Team>()....

另外,我假設您正在執行此操作,但是斷言您的配置有效。 例如:

[Test]
public void AutoMapper_Configuration_IsValid()
{
    Mapper.Initialize(m => m.AddProfile<MyProfile>());
    Mapper.AssertConfigurationIsValid();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM