在nHibernate QueryOver期间不能比较字符串

本文关键字:不能 比较 字符串 nHibernate QueryOver | 更新日期: 2023-09-27 18:02:12

我有一个简单的方法来尝试在用户登录时验证用户,并且我使用Fluent nHibernate进行持久化,因此我很自然地实现ISession.QueryOver<T>来完成这项工作。

内容如下:

var member = session.QueryOver<Member>()
   .Where(m => m.Email == Model.Email)
   .Take(1).SingleOrDefault();

Ok。那么,现在的问题是。

  1. Email地址总是需要比较,不区分大小写。

它们在数据库中应该总是小写。我为这一切付出了巨大的努力。事实上,接受Email Address<input>在它上面有一个只允许小写字母的验证规则。但这还不够好,我想做得更深入,确保一切都是犹太的。

所以我试着做这个…

var member = session.QueryOver<Member>()
   .Where(m => String.Compare
         (m.Email, Model.Email, StringComparison.OrdinalIgnoreCase) == 0)
   .Take(1).SingleOrDefault();

我得到一个异常,nhibernate不能使用String.Compare方法。

我意识到我可以用简单的ToLower()方法来解决这个问题,但是可能存在我想要比其他类型的比较更细粒度的情况。

谁能告诉我怎么解决这个问题?

在nHibernate QueryOver<T>期间不能比较字符串

有多种方法可以做到这一点,使用IsInsensitiveLike:

   var member= Session.QueryOver<Member>()
       .WhereRestrictionOn(m=>m.Email).IsInsensitiveLike(Model.Email)
       .Take(1).SingleOrDefault();

如果@VahidN使用默认排序规则和/或指定显式排序规则的答案不起作用,可以切换到sql方言特定的大小写转换,如下所示:

return _session.QueryOver<Registration>()
        .WhereEqualsIgnoreCase(r => r.Name, userName)   
        .Future().SingleOrDefault();

实现如下:

static class NHibernateCaseInsensitiveWhereExtensions
{
    public static IQueryOver<T, T2> WhereEqualsIgnoreCase<T, T2>(this IQueryOver<T, T2> that, Expression<Func<T, object>> column, string value)
    {
        return
            that.Where(
                Restrictions.Eq(
                    Projections.SqlFunction(
                        "upper", 
                        NHibernateUtil.String,
                        Projections.Property(column)),
                    value.ToUpper()));
    }
}

SQL Server文本匹配不区分大小写。如果不喜欢这样,则必须更改排序 (SQL_Latin1_General_CP1_CS_AS)。因此,您不需要更改任何内容(服务器端或客户端)。