简体   繁体   English

在NHibernate中更新时跳过属性

[英]Skip property on update in NHibernate

Say I have an User entity and it haves a Password property which is not nullable : 说我有一个用户实体,它有一个不能为nullPassword属性:

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

In the create action, I manually set the Password value as it is a generated hash. 在创建操作中,我手动设置了Password值,因为它是生成的哈希值。 It never goes to the View. 它永远不会进入视图。

In the update, I try to save it, but I don't have the Password value. 在更新中,我尝试保存它,但是没有Password值。 I get this error for Password propery: 我收到有关Password属性的错误消息:

PropertyValueException: not-null property references a null or transient value PropertyValueException:非null属性引用null或瞬态值

This is my Update method: 这是我的Update方法:

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

How can I tell NHibernate to ignore a property in an update? 如何告诉NHibernate在更新中忽略属性?

Note: This is not the same as this question . 注意:这与这个问题不同

Update: 更新:

Here is how I use it: The Password property never goes to any View. 这是我的用法: Password属性永远不会进入任何视图。 Even in the Login action I have a generic LoginViewModel , only for it's view. 即使在Login操作中,也只有它的视图才具有通用的LoginViewModel 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. Get the entity before Update and update explicitly 在更新之前获取实体并明确更新

     // 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); 

    In addition to that, you can use Dynamic-Update . 除此之外,您还可以使用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. 然后,NHibernate将仅更新更改的属性,而不会在更新实体时全部更新。 Otherwise NHibernate can't know which properties has changed and will update all. 否则,NHibernate无法知道哪些属性已更改,并将全部更新。 DynamicUpdate should only work when you got the entity from NHibernate. 仅当您从NHibernate获得实体时,DynamicUpdate应该才起作用。 The Entity is then bound to the Context and NHibernate can track changes. 然后将实体绑定到上下文,NHibernate可以跟踪更改。

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

     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(); } } 
  2. Use different classes for different behaviours 对不同的行为使用不同的类

    You can declare different classes for the same Entity. 您可以为同一实体声明不同的类。 One class for User creation or password resetting that contains the password property. 一种用于创建用户或重置密码的类,其中包含password属性。 And one class for simple updates that don't need the password property. 一类不需要密码属性的简单更新。 FluentNhibernate allows you to map different classes for the same table. FluentNhibernate允许您为同一表映射不同的类。 But you need a little more effort in mapping or rather in AutoMappingOverrides. 但是,您在映射或AutoMappingOverrides中需要付出更多的努力。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM