在NHibernate中更新时跳过属性 [英] Skip property on update in NHibernate

查看:87
本文介绍了在NHibernate中更新时跳过属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一个 User 实体,它有一个Password属性,该属性不能为空:

Say I have an User entity and it haves a Password property which is not nullable:

Map((x) => x.Password).Column("PASSWORD").Not.Nullable();

在创建动作中,我手动设置Password值,因为它是生成的哈希.它永远不会进入视图.

In the create action, I manually set the Password value as it is a generated hash. It never goes to the View.

在更新中,我尝试保存它,但没有Password值.我收到Password属性的错误:

In the update, I try to save it, but I don't have the Password value. I get this error for Password propery:

PropertyValueException:not-null属性引用一个空值或瞬态值

PropertyValueException: not-null property references a null or transient value

这是我的更新方法:

public bool Update(UserViewModel input)
{
    if (!IsValid(input))
        return false;

    var user = Mapper.Map<User>(input);

    this.UserRepository.Update(user); // <- this is a wrapper for NH's Session.Update()

    return true;
}

如何告诉NHibernate在更新中忽略属性?

How can I tell NHibernate to ignore a property in an update?

注意:这与此问题不同.

Note: This is not the same as this question.

更新:

这是我的用法:Password属性永远不会进入任何视图.即使在登录"操作中,我也有一个通用的LoginViewModel,仅用于查看.该属性仅在登录过程中使用,可以在重置密码功能中进行更新,该功能将生成新密码并将其发送到相关的用户电子邮件.

Here is how I use it: The Password property never goes to any View. Even in the Login action I have a generic LoginViewModel, only for it's view. That property is only used in the login process and it could be updated in the Reset password feature, where a new password is generated and sent to the related user e-mail.

推荐答案

我看到实现这一目标的两种可能性

I see 2 possibilities to achieve that

  1. 在更新之前获取实体并明确更新

// use 'Get()' because it uses the NHibernate cache
// if you already loaded the entity, it won't query the db and read it from the cache
var user = this.UserRepository.Get(input.Id); 
user.PropertyToUpdate = ...;
this.UserRepository.Update(user);

除此之外,您还可以使用Dynamic-Update. 但这仅适用于绑定到Session的实体.然后,NHibernate将仅更新更改的属性,而不是在更新实体时全部更新.否则,NHibernate无法知道哪些属性已更改,并将全部更新.仅当您从NHibernate获得实体时,DynamicUpdate应该才起作用.然后将实体绑定到上下文,NHibernate可以跟踪更改.

In addition to that, you can use Dynamic-Update. But this will only work with entities that are bound to the Session. NHibernate will then only update the changed properties and not all while you are updating a entity. Otherwise NHibernate can't know which properties has changed and will update all. DynamicUpdate should only work when you got the entity from NHibernate. The Entity is then bound to the Context and NHibernate can track changes.

如果所有实体都已自动映射,则可以使用ClassConvention将DynamicUpdate设置为所有实体(或仅过滤所需的实体):

If all your entities are auto mapped you can use a ClassConvention to set DynamicUpdate to all your entities (or just filter the ones you want):

public class ClassConvention : IClassConvention
{
    public void Apply(IClassInstance instance)
    {
        instance.DynamicUpdate();
    }
}

作为另一种选择,您可以使用显式映射覆盖:

As another option you can use a explicit mapping override:

public class UserOverride : IAutoMappingOverride<User>
{
    public void Override(AutoMapping<User> mapping)
    {
        mapping.DynamicUpdate();
    }
}

  • 对不同的行为使用不同的类

    您可以为同一实体声明不同的类.一种用于创建用户或重置密码的类,其中包含password属性.一类不需要密码属性的简单更新. FluentNhibernate允许您为同一张表映射不同的类.但是您需要在映射上或者在AutoMappingOverrides中花费更多的精力.

    You can declare different classes for the same Entity. One class for User creation or password resetting that contains the password property. And one class for simple updates that don't need the password property. FluentNhibernate allows you to map different classes for the same table. But you need a little more effort in mapping or rather in AutoMappingOverrides.

    这篇关于在NHibernate中更新时跳过属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆