2017-10-04 33 views
1

我有一種情況,當我更新子表中的一行時,實體框架核心(2.0)正在向父表執行附加工作。我已經把原因固定在AutoMapper生成的unflattened對象樹中沒有設置的值(我並不是說它是AutoMapper中的一個錯誤,它可能與我的代碼有關)。automapper unflatten排除父對象的值

我在API開發方面使用ASP.NET Core 2.0,C#,EF Core 2.0和AutoMapper。該數據庫已經存在,並且EF類從它腳手架。

爲了保持簡短,子表是Note,父表是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的主鍵。

配置

這是AutoMapper配置:

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

讀取數據

數據檢索的結果我得到預期的結果和父記類型描述被填充。

// 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控制器DTO映射到實體

Mapper.Map<Note>(noteDto) 

然後,當它通過代表傳遞給EF ository代碼,EF嘗試添加一個NoteType行ID爲0。不平對象樹看起來像這樣:

Note 
    NoteBookId = 29 
    NoteSeqNo = 19 
    NoteTypeId = 18 
    NoteTypeNoteTypeDesc = "ABCDE" 
    NoteText = "My notes updated." 
    NoteType.NoteTypeDesc = "ABCDE" 
    NoteType.NoteTypeId = 0 

父ID柱(NoteType.NoteTypeId)值是0並且沒有被分配18的值,其是我的預期。

(在調試過程中,我手動將NoteType.NoteTypeId設置爲18,以確保EF對此沒有任何影響)。

爲了解決這個問題,我暫時在資源庫代碼中的Note中取消NoteType。

我是否應該期望AutoMapper使用setter填充所有的父屬性,還是錯過了一些配置?或許我的方法存在明顯的缺陷?

回答

0

當AutoMapper反轉映射時,它必須從扁平對象中收集嵌套對象的所有信息。您的DTO僅包含地圖NoteType -> NoteTypeDesc的值。不是因爲NoteType -> NoteTypeId,所以AM真的不知道從哪裏獲得價值。

如果你想只依靠扁平化,改變,唯一的辦法是扁平NoteTypeId添加到DTO除了不平之一:

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

是的,但他說Note.NoteType不爲空,並有Id 0,對不對? :)這是因爲反轉映射和默認的展平/解閉。 –

+0

我想這取決於目的是什麼。如果目的是讓Note.NoteType爲空,我的答案適用,否則是你的。 –

+0

謝謝!該便士已經下降:)。額外的配置是我需要添加,以便unflattened id被填充。 (我不知道爲什麼我認爲automapper會連接點)。 – Craig

0

MapFrom-s(包括默認解開)are reversed now。您可以放棄ReverseMap並創建地圖,忽略Note.NoteType或忽略違規路徑Note.NoteType.NoteTypeDesc。

+0

感謝您的評論,但我不明白你的建議如何幫助我。我不想放棄反向貼圖,也不想忽略NoteType。我真的很想知道爲什麼AutoMapper不能完全解開NoteType。 – Craig

+0

您是否閱讀過我鏈接的文檔? :) –