Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Nhibernate ASP.NET MVC中的自动映射更新操作_Nhibernate_Asp.net Mvc 3_Automapper - Fatal编程技术网

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