尽管使用opt => AutoMapper将相关实体设置为null opt.Ignore()

时间:2016-01-08 17:44:27

标签: c# asp.net-mvc entity-framework automapper

我试图通过AutoMapper(通过NuGet安装的最新版本)映射两个相同类型的对象。我的代码:

public class School
{
    public int Id {get; set;}
    public string Name{get; set;}
    public User CreatedBy {{get; set;}
}

public class User
{
   public int Id {get; set;}
   public string Code {get; set;}
}

我有MV 6和MVC。在编辑中,学校的副本被提供给视图,当它被提交时,我试图将它映射到数据库中的那个,以便我可以保存它。我不希望在映射时更改用户在学校。所以我的代码是:

在编辑控制器操作

//...
var school = db.Schools.FirstOrDefault(s => s.Id == viewModel.SchoolId);

Mapper.CreateMap<School, School>().ForMember(r => r.User, opt => opt.Ignore());
//viewModel.School is an object of School type.
school = Mapper.Map<School>(viewModel.School);
//Here school.User is set to null!

惊讶地看到school.User为空。我以为我已经明确排除映射器忽略目标值。我认为在这种情况下,它应该保留source属性。我也试过UseDestinationValue()。但没有运气。是什么导致了这个错误?我有时想知道是否有其他更好的方法可用于特定于EF的对象映射。

1 个答案:

答案 0 :(得分:4)

这种情况正在发生,因为您正在创建一个新的学校实例,而不是更新您从数据库中提取的实例。

而不是:

var school = db.Schools.FirstOrDefault(s => s.Id == viewModel.SchoolId);
school = Mapper.Map<School>(viewModel.School);

执行:

var school = db.Schools.FirstOrDefault(s => s.Id == viewModel.SchoolId);
Mapper.Map(viewModel.School, school);

这不会创建新实例,而是更新您已有的实例。

顺便说一下,你不应该在你的动作方法中创建地图 - 这应该在你的应用程序初始化中运行,因为它不需要在每个方法上运行。