gpt4 book ai didi

nhibernate - ASP.NET MVC 中的 AutoMapper 更新操作

转载 作者:行者123 更新时间:2023-12-03 16:28:26 25 4
gpt4 key购买 nike

对于某些人来说,这可能很简单,但是我有点困惑,找不到合适的例子。假设我正在使用 View 模型,并且我的 POST 操作采用该 View 模型。通常我会按照以下几行做一些事情:

    [HttpPost]
public ActionResult Update(UserViewModel uvm)
{
User user = Mapper.Map<UserViewModel, User>(uvm);
_repository.Update(user);

return RedirectToAction("Index");
}

虽然这不是全貌。映射可以正常工作,但是如果我只是更新我映射的内容,那么它会删除数据库中有值(value)的数据,因为当然在这种情况下我不会更新密码或其他详细信息。

我的仓库看起来像这样:

    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;
}

[我正在使用 NHibernate,因此它会在 session 关闭后(在请求完成后)自动为我将对象保存回数据库。]

所以我的问题是,我应该在我的存储库中加载“用户”实体,然后更新我想要的值,然后将其保存回去,还是有其他方法可以做到这一点?我问的原因是因为它似乎有点......“手动”,如果你明白我的意思?也许是正确的,但我只是想看看在这方面有更多经验的人的意见。

干杯

最佳答案

我使用以下方法:

[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());

然后:

[HttpPost]
public ActionResult Update(UserViewModel uvm)
{
// Fetch the original model we would like to update
User user = _userRepository.FindById(uvm.Id);

Mapper.Map(uvm, user);
// At this stage the user model will have its
// Forename, Surname and EmailAddress properties
// updated from the view model and its Password property
// will remain the one we got from the repository

_userRepository.Update(user);

return RedirectToAction("Index");
}

更新 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>();
}
}

然后有一个注册所有映射器的注册类:

public class MappingsRegistry
{
public static void Configure()
{
Mapper.AddProfile(new UsersProfile());
Mapper.AddProfile(new SomeOtherProfile());
...
}
}

Application_Start 中调用:

MappingsRegistry.Configure();

最后我的 Controller 有一个映射引擎的引用:

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 属性传递给构造函数,并且在您的单元测试中显然用适当的模拟替换它们。

关于nhibernate - ASP.NET MVC 中的 AutoMapper 更新操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6124095/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com