這是一個很長的實例。創建新實例而不是映射屬性的自動映射器
所以,我有一個模型和一個viewmodel,我從AJAX請求更新。網絡API控制器接收視圖模型,這是我然後使用AutoMapper象下面更新現有的模型:
private User updateUser(UserViewModel entityVm)
{
User existingEntity = db.Users.Find(entityVm.Id);
db.Entry(existingEntity).Collection(x => x.UserPreferences).Load();
Mapper.Map<UserViewModel, User>(entityVm, existingEntity);
db.Entry(existingEntity).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch
{
throw new DbUpdateException();
}
return existingEntity;
}
我已經automapper配置像這樣的用戶 - > UserViewModel(和背面)的映射。
Mapper.CreateMap<User, UserViewModel>().ReverseMap();
(請注意,顯式設置相對地圖和省略ReverseMap表現出相同的行爲)
我在與模型/視圖模型的構件,其不同的對象的ICollection的一個問題:
[DataContract]
public class UserViewModel
{
...
[DataMember]
public virtual ICollection<UserPreferenceViewModel> UserPreferences { get; set; }
}
的相應的模型是像這樣:
public class User
{
...
public virtual ICollection<UserPreference> UserPreferences { get; set; }
}
問題:
用戶和UserViewModel類的每個屬性映射正確地,除了以上所示的使用UserPreferences/UserPreferenceViewModels的ICollections
。當這些集合從ViewModel映射到Model而不是映射屬性時,將從ViewModel創建一個UserPreference對象的新實例,而不是使用ViewModel屬性更新現有對象。
型號:
public class UserPreference
{
[Key]
public int Id { get; set; }
public DateTime DateCreated { get; set; }
[ForeignKey("CreatedBy")]
public int? CreatedBy_Id { get; set; }
public User CreatedBy { get; set; }
[ForeignKey("User")]
public int User_Id { get; set; }
public User User { get; set; }
[MaxLength(50)]
public string Key { get; set; }
public string Value { get; set; }
}
和相應的視圖模型
public class UserPreferenceViewModel
{
[DataMember]
public int Id { get; set; }
[DataMember]
[MaxLength(50)]
public string Key { get; set; }
[DataMember]
public string Value { get; set; }
}
而且automapper配置:
Mapper.CreateMap<UserPreference, UserPreferenceViewModel>().ReverseMap();
//also tried explicitly stating map with ignore attributes like so(to no avail):
Mapper.CreateMap<UserPreferenceViewModel, UserPreference>().ForMember(dest => dest.DateCreated, opts => opts.Ignore());
當映射一個UserViewModel實體到用戶,UserPreferenceViewModels的ICollection的是還它應該像映射用戶的UserPreferences的ICollection一樣。
但是,如果發生這種情況,單個UserPreference對象的屬性(如「DateCreated」,「CreatedBy_Id」和「User_Id」)將被忽略,就像創建新對象而不是被複制的單個屬性一樣。
這進一步顯示爲證據,因爲在映射UserViewModel時,集合中只有1個UserPreference對象,當檢查DbContext時,映射語句後有兩個本地UserPreference對象。一個看起來是從ViewModel創建的新對象,另一個來自現有模型的原始對象。
如何讓automapper更新現有Model的集合的成員,而不是從ViewModel集合中實例化新成員?我在這裏做錯了什麼?
截圖演示之前/之後的Mapper。地圖()
您可能需要重寫'UserPreference'和'UserPreferenceViewModel'中的'GetHashCode',以便集合可以識別它們是相同的。也許automapper有一些魔術,但我很懷疑 – HaroldHues
是的,必須複製/粘貼錯誤的行CreateMap線。我正在查看當前的GetHashCode覆蓋,如果發現任何內容,我會報告回來。謝謝你的幫助。 –
您需要退後一步並停止使用AutoMapper從ViewModel映射到您的實體或域模型。 AutoMapper沒有爲此做,並不會按預期工作。使用AutoMapper ** ONLY **從實體/域模型映射到ViewModel/DTO/BindingModel **,從不**其他方式。這樣做是由AutoMapper作者 – Tseng