2017-10-04 23 views
1

자식 테이블의 행을 업데이트 할 때 엔터티 프레임 워크 코어 (2.0)가 부모 테이블에 추가 작업을 수행하는 상황이 있습니다. 필자는 AutoMapper에 의해 생성 된 평탄하지 않은 개체 트리에서 설정되지 않은 값을 지적했습니다 (AutoMapper에서 오류라고 말하는 것은 아니며, 아마도 내 코드와 관련이 있습니다).automapper unflatten이 부모 개체의 값을 제외합니다.

저는 API 개발 측면에서 ASP.NET Core 2.0, C#, EF Core 2.0 및 AutoMapper를 사용하고 있습니다. 데이터베이스가 이미 존재하고 EF 클래스가이 클래스에서 스캐 폴딩합니다.

간결하게 유지하기 위해 자식 테이블은 참고이고 부모 테이블은 NoteType입니다. 다음과 같이 EF 클래스 (제거 외부 열)은 다음과 같습니다

//Entity classes 
public partial class Note 
    { 
     public int NoteBookId { get; set; } 
     public short NoteSeqNo { get; set; } 
     public short NoteTypeId { get; set; } 
     public string NoteText { get; set; } 

     public NoteBook NoteBook { get; set; } 
     public NoteType NoteType { get; set; } 
    } 

public partial class NoteType 
    { 
     public NoteType() { Note = new HashSet<Note>(); } 
     public short NoteTypeId { get; set; } 
     public string NoteTypeDesc { get; set; } 
     public ICollection<Note> Note { get; set; } 
    } 

//DTO class 
    public class NoteDto 
    { 
     public int NoteBookId { get; set; } 
     public short NoteSeqNo { get; set; } 
     public short NoteTypeId { get; set; } 
     public string NoteTypeNoteTypeDesc { get; set; } 
     public string NoteText { get; set; } 
    } 

public class NoteTypeDto 
    { 
     public short NoteTypeId { get; set; } 
     public string NoteTypeDesc { get; set; } 
    } 
  • (NoteBookId + NoteSeqNo) 참고의 기본 키입니다.
  • NoteTypeId는 NoteType의 기본 키입니다.

    // config in startup.cs 
    config.CreateMap<Note,NoteDto>().ReverseMap(); 
    config.CreateMap<NoteType,NoteTypeDto>().ReverseMap(); 
    

    내가 예상 결과 및 부모 메모를 얻을 데이터 검색의 결과로 데이터를

    읽기 :

구성

이것은 AutoMapper 구성입니다 유형 설명이 채워집니다.

// EF get note in repository 
      return await _dbcontext.Note 
       .Where(n => n.NoteId == noteId && n.NoteSeqNo == noteSeqNo) 
       .Include(n => n.NoteType) 
       .FirstOrDefaultAsync(); 

// Get note function in API controller 
       Note note = await _repository.GetNoteAsync(id, seq); 
       NoteDto noteDto = Mapper.Map<NoteDto>(note); 

예 JSON 결과 : 프로세스가 업데이트하는 동안 반전

{ 
    "noteBookId": 29, 
    "noteSeqNo": 19, 
    "noteTypeId": 18, 
    "noteTypenoteTypeDesc": "ABCDE", 
    "noteText": "My notes here." 
} 

업데이트 데이터는 API 컨트롤러는 기업

Mapper.Map<Note>(noteDto) 
에 DTO를 매핑

그런 다음 담당자가 EF로 전달하면 ository 코드 EF 이드 0. 평탄화 오브젝트 트리와 NoteType 행을 추가하는 시도는 다음과 같다 :

상위 ID 컬럼 (NoteType.NoteTypeId) 값이 0이고, 18의 값이 할당되지
Note 
    NoteBookId = 29 
    NoteSeqNo = 19 
    NoteTypeId = 18 
    NoteTypeNoteTypeDesc = "ABCDE" 
    NoteText = "My notes updated." 
    NoteType.NoteTypeDesc = "ABCDE" 
    NoteType.NoteTypeId = 0 

어느 내가 기대했던 것입니다.

(디버깅 중에 수동으로 NoteType.NoteTypeId를 18로 설정하여 EF가 아무 것도하지 않았는지 확인하십시오).

이 순간을 해결하려면 저장소 코드의 메모에서 NoteType을 무효화하십시오.

AutoMapper가 모든 상위 속성을 설정자로 채우거나 일부 구성을 놓치기를 기대해야합니까? 아마도 내 접근 방식에는 눈부신 결함이 있습니까?

답변

0

AutoMapper가 매핑을 되돌릴 때 플랫 개체에서 중첩 된 개체에 대한 모든 정보를 수집해야합니다. 귀하의 DTO는 매핑 NoteType -> NoteTypeDesc에 대한 값만 가지고 있습니다. NoteType -> NoteTypeId을위한 것이 아니기 때문에, AM은 그 값을 어디서 얻을지 전혀 모른다.

만 병합에 의존 할 경우

은 그것을 바꿀 수있는 유일한 방법은 평탄화 한 외에 DTO에 평평 NoteTypeId을 추가하는 것입니다

public class NoteDto 
{ 
    public int NoteBookId { get; set; } 
    public short NoteSeqNo { get; set; } 
    public short NoteTypeId { get; set; } // Not flattened 
    public short NoteTypeNoteTypeId { get; set; } // Flattened 
    public string NoteTypeNoteTypeDesc { get; set; } 
    public string NoteText { get; set; } 
} 

대안은이를 추가하는 것입니다 매핑 :

config.CreateMap<Note, NoteDto>() 
    .ForMember(dest => dest.NoteTypeId, 
     e => e.MapFrom(src => src.NoteType.NoteTypeId)) 
    .ReverseMap(); 
+0

예,하지만 그는 메모를합니다 .NoteType은 null이 아니며 ID가 0입니다. 맞습니까? :) 이것은 반전 된지도와 기본 병합/비 평탄화 때문입니다. –

+0

나는 그것이 목적이 무엇인지에 달려 있다고 생각합니다. Note.NoteType을 null로 설정하는 것이 목적이라면 내 대답이 적용되고 그렇지 않으면 내 답변이 적용됩니다. –

+0

고마워요! 페니가 떨어졌습니다 :). 추가 설정은 덧붙일 필요가 없기 때문에 unflattened id가 채워집니다. (필자는 automapper가 점들을 연결한다고 생각하는 이유를 모른다.) – Craig

0

MapFrom-s (기본값 인 비평 면화 포함) are reversed now. ReverseMap을 삭제하고 맵을 작성하거나, Note.NoteType을 무시하거나, 위반 경로 인 Note.NoteType.NoteTypeDesc를 무시할 수 있습니다.

+0

의견을 주셔서 감사합니다. 귀하의 제안이 나를 어떻게 돕는 지 이해할 수 없습니다. 리버스 맵을 삭제하고 NoteType을 무시하고 싶지 않습니다. 나는 AutoMapper가 NoteType을 완전히 unflatten하지 않는 이유를 정말로 알고 싶다. – Craig

+0

내가 링크 된 문서를 읽었습니까? :) –