如何覆盖特定NHibernate类的equals

时间:2009-07-15 12:44:52

标签: c# nhibernate equals gethashcode

我正在努力弄清楚我应该如何覆盖equals并获取我使用NHibernate编写的类的哈希码。

基本业务场景是用户无法在90天限制内重复使用相同的密码。

所以我有一个“用户”,它有很多“历史密码”......用户类很容易,因为我只是在等号中使用登录。下面是我的HistoricalPassword类。

public class HistoricalPassword
{
    public virtual int HistoricalPasswordId { get; set; }
    public virtual User User { get; set; }
    public virtual DateTime ChangeDate { get; set; }
    public virtual string FormerPassword { get; set; }
}

从商业意义上说,用户和ChangeDate的组合会让我平等。但是...在equals方法中引用用户似乎不正确(因为有一件事会导致延迟加载发生)......而且我从使用HistoricalPasswordId的PK读取的内容也是一个禁忌同样。

任何人都可以提供一些关于如何为此重叠等于的建议吗?

编辑::: 我想我可能在问这个问题的方式上有点误导。我并不担心如何执行确保密码不被重用的业务规则...也不知道如何知道两个密码是否相等或是否安全。我真正想知道的是在与NHibernate有关的实体级别如何为这个对象重写Equals,以便NHibenate不会在会话和/或缓存中结束dupe。根据NHibernate doc(https://www.hibernate.org/hib_docs/nhibernate/html/persistent-classes.html),我应该使用Business key equality来覆盖equals。在这种情况下,我只是不确定在比较中使用User的引用对象是否是个好主意。

3 个答案:

答案 0 :(得分:2)

我不会为此重写Equals - 你没有断言这些记录是相同的,只是他们引用相同的密码,不是吗?

当然,您只需要一个HQL或条件查询,为您提供过去90天内设置的历史密码?

编辑:您也可以查看存储密码的方式。数据库中的明文密码不是一个好主意。您可能有一个NHibernate用户类型正在将加密的密码解密为我们可以看到的字符串属性,当然......

答案 1 :(得分:0)

我认为HistoricalPassword是一个值对象,而不是一个实体。

因此,这意味着它的'ID'将由其所有属性的值决定。

答案 2 :(得分:0)

你可以通过几种方式解决这个问题。

如果你想使用相等来做,那么用户将参与其中,特别是用户的PK。平等将是用户PK +密码。日期无关紧要。然而,这可能使事情变得复杂,我可能不会这样做。

另一种方法是仅使用密码进行相等,因为这是您最终要比较的内容。用户只能在查询中使用,同样也可以在更改日期使用。

执行HQL查询以获取user = {user}的历史密码并更改日期< (今天 - 90)。这将返回{user}过去90天内的所有密码。完成该问题后,您需要做的就是比较密码以查看是否有匹配,因为您已将结果集减少到{user}过去90天内的那些密码。

最后,如上所述,只需对{user}执行HQL查询,其中日期已更改< 90和密码= {新密码}。如果您收到任何结果,则表示密码已在过去90天内使用过。

最后,正如上面提到的,这些比较都假设您要么使用明文密码,要么加密新密码以与旧密码进行比较。以太方式,必须采取措施来解决密码的安全问题。