[英]Skip property on update in NHibernate
说我有一个用户实体,它有一个不能为null的Password
属性:
Map((x) => x.Password).Column("PASSWORD").Not.Nullable();
在创建操作中,我手动设置了Password
值,因为它是生成的哈希值。 它永远不会进入视图。
在更新中,我尝试保存它,但是没有Password
值。 我收到有关Password
属性的错误消息:
PropertyValueException:非null属性引用null或瞬态值
这是我的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;
}
如何告诉NHibernate在更新中忽略属性?
注意:这与这个问题不同 。
更新:
这是我的用法: Password
属性永远不会进入任何视图。 即使在Login操作中,也只有它的视图才具有通用的LoginViewModel
。 该属性仅在登录过程中使用,并且可以在“ 重置密码”功能中进行更新,该功能会生成新密码并将其发送到相关的用户电子邮件。
我看到实现这一目标的两种可能性
在更新之前获取实体并明确更新
// 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
。 但这仅适用于绑定到会话的实体。 然后,NHibernate将仅更新更改的属性,而不会在更新实体时全部更新。 否则,NHibernate无法知道哪些属性已更改,并将全部更新。 仅当您从NHibernate获得实体时,DynamicUpdate应该才起作用。 然后将实体绑定到上下文,NHibernate可以跟踪更改。
如果所有实体都已自动映射,则可以使用ClassConvention
将DynamicUpdate设置为所有实体(或仅过滤所需的实体):
public class ClassConvention : IClassConvention { public void Apply(IClassInstance instance) { instance.DynamicUpdate(); } }
作为另一个选择,您可以使用显式映射覆盖:
public class UserOverride : IAutoMappingOverride<User> { public void Override(AutoMapping<User> mapping) { mapping.DynamicUpdate(); } }
对不同的行为使用不同的类
您可以为同一实体声明不同的类。 一种用于创建用户或重置密码的类,其中包含password属性。 一类不需要密码属性的简单更新。 FluentNhibernate允许您为同一表映射不同的类。 但是,您在映射或AutoMappingOverrides中需要付出更多的努力。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.