【问题标题】:How to make Nhibernate Case sensitive query using QueryOver?如何使用 QueryOver 进行 Nhibernate 区分大小写的查询?
【发布时间】:2014-05-21 12:37:42
【问题描述】:

我有一个带有用户表的简单数据库,它有一个简单的管理员用户

用户名=“管理员”
密码="管理员"

我正在使用 NHibernate 来查询此表以登录表单。 假设登录表单以大写形式插入UserName="ADMIN"password="ADMIN"

系统不应允许登录。但是,当我使用这样的查询时

using (var session = NhibernateHelper.OpenSession())
{
  return new List<User>
         (session.QueryOver<User>()
                 .Where(u => u.UserName == userName)
                 .And(u => u.Password == password)
                 .Future());
}}

系统忽略区分大小写并选择用户。那么如何进行大小写敏感查询呢?

【问题讨论】:

标签: nhibernate queryover


【解决方案1】:

我们可以直接指定COLLATE作为SQL列评估的一部分

session
    .QueryOver<User>()
    // expecting that user name could be any case 
    // if not, we can use the same as for password below
    .Where(u => u.UserName == userName)
    // instead of this
    //.And(u => u.Password == password)
    .And(Expression.Sql(" Password = ? COLLATE Latin1_General_CS_AS"
       , password, NHibernateUtil.String));
    .Future()
    ;

上述语句将使用Latin1_General_CS_AS,其中CS 表示:区分大小写,AS 表示区分重音

此外,还有一些自定义 LikeExpression 的草案,它可以将 COLLATE 字符串用作 const 或来自设置:

【讨论】:

  • 没有任何扩展方法可以做到这一点吗?
  • 好吧,在这种情况下,据我所知 - 不。但是很容易引入新的、自定义的;)我会说。
  • 我是 Nhibernate 的新手,你能建议参考一下如何创建自定义的吗?谢谢
  • 扩展方法与 NHibernate 无关!!! ;) 这些都是 C# 世界! stackoverflow.com/questions/13840413此链接包含如何做漂亮扩展的草稿;)
  • .And(Expression.Sql(" Password = ? COLLATE Latin1_General_CS_AS" , password, NHibernateUtil.String)); Mysql 不支持。
【解决方案2】:

另一种方法,不是使用 QueryOver,而是使用 LINQ:

session.Query<User>().Where(u => SqlMethods.Like(u.Username, "something")).ToList();

【讨论】:

  • Like 与 equals 有非常不同的比较语义,这带来了一系列安全问题
  • 根据数据库的设置方式,这可能不会产生区分大小写的比较。
【解决方案3】:

或者,使用标准:

session.CreateCriteria(typeof(User), "u").Add(Restrictions.Like(Projections.Property("u.Username"), "something")).List<Username>();

【讨论】:

  • Like 与 equals 有非常不同的比较语义,这带来了一整套安全问题
  • 如果我提交的用户名是例如Ad%,那么我会知道您是否有一个(单个)用户,称为 Admin 或 Administrator。这种通用方法可以启用任意数量的用户枚举
  • 这足以解释它吗?
  • 这很讽刺。您的回答只是常识,只是部分的(例如,没有提及索引)。
  • 安全问题并不讽刺。对我来说,索引在相关性方面远远落后于它。虽然您可能熟悉权衡并意识到问题的有效性,但以这种方式回应(无论是讽刺、被动攻击性还是真正的询问)并不能帮助人们看到这些答案并从表面上理解它们。确实是买者自负:)
【解决方案4】:

最后,QueryOver:

session.QueryOver<User>().Where(Expression.Sql("Username LIKE ?", "something", NHibernateUtil.String)).List<User>()

【讨论】:

  • Like 与 equals 有非常不同的比较语义,这带来了一整套安全问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-21
  • 1970-01-01
  • 2014-04-29
  • 2013-11-08
  • 2012-12-16
相关资源
最近更新 更多