Nhibernate ASP.NET MVC中的自动映射更新操作
对于一些人来说,这可能是非常直截了当的,但是我有点困惑,找不到一个像样的例子。假设我正在使用视图模型,并且我的后期操作在该视图模型中执行。通常我会按照以下思路做一些事情:Nhibernate ASP.NET MVC中的自动映射更新操作,nhibernate,asp.net-mvc-3,automapper,Nhibernate,Asp.net Mvc 3,Automapper,对于一些人来说,这可能是非常直截了当的,但是我有点困惑,找不到一个像样的例子。假设我正在使用视图模型,并且我的后期操作在该视图模型中执行。通常我会按照以下思路做一些事情: [HttpPost] public ActionResult Update(UserViewModel uvm) { User user = Mapper.Map<UserViewModel, User>(uvm); _repository.Update(us
[HttpPost]
public ActionResult Update(UserViewModel uvm)
{
User user = Mapper.Map<UserViewModel, User>(uvm);
_repository.Update(user);
return RedirectToAction("Index");
}
[HttpPost]
公共操作结果更新(UserViewModel uvm)
{
User=Mapper.Map(uvm);
_更新(用户);
返回操作(“索引”);
}
虽然这还不是全貌。映射可以很好地工作,但是,如果我只是更新映射的内容,那么它将删除数据库中的有价值数据,因为在这种情况下,我当然不会更新密码或其他详细信息
我的存储库如下所示:
public void Update(User user)
{
User u = Session.QueryOver<User>().Where(x => x.UserName == user.UserName).SingleOrDefault();
if (u == null)
throw new Exception("User not found");
u.Forename = user.Forename;
u.Surname = user.Surname;
u.EmailAddress = user.EmailAddress;
}
公共作废更新(用户)
{
User u=Session.QueryOver()。其中(x=>x.UserName==User.UserName)。SingleOrDefault();
如果(u==null)
抛出新异常(“未找到用户”);
u、 Forename=user.Forename;
u、 姓氏=用户。姓氏;
u、 EmailAddress=user.EmailAddress;
}
[我正在使用NHibernate,因此一旦会话关闭(请求完成后),它会自动将对象保存回数据库。]
因此,我的问题是,在我的存储库中,我应该加载“用户”实体,然后更新我想要的值,然后将其保存回去,还是有其他方法可以做到这一点?我问的原因是因为它似乎有点。。。“手册”如果你明白我的意思?也许这是正确的,但我只是想看看在这方面有更多经验的人的意见
干杯我使用以下方法:
[HttpPost]
public ActionResult Update(UserViewModel uvm)
{
User user = _userRepository.FindById(uvm.Id);
user.Forename = uvm.Forename;
user.Surname = uvm.Surname;
user.EmailAddress = uvm.EmailAddress;
_userRepository.Update(user);
return RedirectToAction("Index");
}
更新: 要解决有关
AutoMapper
的评论,请执行以下操作:
让我们以以下类为例:
public class UserViewModel
{
public string Forename { get; set; }
public string Surname { get; set; }
public string EmailAddress { get; set; }
}
public class User
{
public string Forename { get; set; }
public string Surname { get; set; }
public string EmailAddress { get; set; }
public string Password { get; set; }
}
我们不想在UI中修改用户密码。因此,我们向AutoMapper表达我们的意向:
Mapper
.CreateMap<UserViewModel, User>()
.ForMember(dest => dest.Password, opt => opt.Ignore());
更新2: 为了解决有关配置AutoMapper的评论中的问题,我通常使用配置文件:
public class UsersProfile : Profile
{
protected override void Configure()
{
Mapper
.CreateMap<UserViewModel, User>()
.ForMember(dest => dest.Password, opt => opt.Ignore());
Mapper
.CreateMap<User, UserViewModel>();
}
}
在应用程序\u Start
中调用:
MappingsRegistry.Configure();
最后,我的控制器有一个映射引擎的引用:
public class UsersController : Controller
{
private readonly IUsersRepository _repository;
private readonly IMappingEngine _mappingEngine;
public ContratsFCController(IUsersRepository repository, IMappingEngine mapperEngine)
{
_repository = repository;
_mapperEngine = mapperEngine;
}
[AutoMap(typeof(User), typeof(UserViewModel))]
public ActionResult Update(int id)
{
var user = _repository.FindById(id);
return View(user);
}
[HttpPost]
public ActionResult Update(UserViewModel uvm)
{
if (!ModelState.IsValid)
{
return View(uvm);
}
var user = _repository.FindById(uvm.Id);
_mapperEngine.Map(uvm, user);
_repository.Update(user);
return RedirectToAction("Index");
}
}
现在剩下的就是指示DI框架将
Mapper.Engine
属性传递给构造函数,在单元测试中,显然用适当的mock替换它们。很高兴知道我走的是正确的道路。在控制器/存储库中这样做有什么好处吗?或者这应该委托给另一个设计用来映射对象的类吗?需要注意的是,Darin的方法并没有使用AutoMapper来映射对象。我通常不会在“返回时”使用AutoMapper,因为我发现我更喜欢将ViewModel直接映射到从repository@Iomaxx这是我的下一个问题,你已经为我澄清了。非常感谢:)您会使用AutoMapper创建对象吗?@Kezzer,请参阅我的AutoMapper更新。在我的初始示例中,我手动执行此操作,因为这更容易,但很明显,在实际应用程序中,您将使用映射工具来避免控制器中单调乏味的逐个属性映射。
MappingsRegistry.Configure();
public class UsersController : Controller
{
private readonly IUsersRepository _repository;
private readonly IMappingEngine _mappingEngine;
public ContratsFCController(IUsersRepository repository, IMappingEngine mapperEngine)
{
_repository = repository;
_mapperEngine = mapperEngine;
}
[AutoMap(typeof(User), typeof(UserViewModel))]
public ActionResult Update(int id)
{
var user = _repository.FindById(id);
return View(user);
}
[HttpPost]
public ActionResult Update(UserViewModel uvm)
{
if (!ModelState.IsValid)
{
return View(uvm);
}
var user = _repository.FindById(uvm.Id);
_mapperEngine.Map(uvm, user);
_repository.Update(user);
return RedirectToAction("Index");
}
}