2011-07-16 8 views
6

ユーザーがログインするときにユーザーを検証する単純な方法がありますが、これは永続性のためにFluent nHibernateを使用しているため、当然ISession.QueryOver<T>を実装します。nHibernate QueryOverの間に文字列を比較できない<T>

以下のようになります。

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

それでは、手元にある問題。

  1. 電子メールアドレスは常に大文字と小文字を区別する必要があります。

は常に小文字のデータベースになります。私はこれを実現させるために大きな痛みを覚えました。実際、Email Addressを受け入れる私の<input>は、小文字のみを許可するための検証規則を持っています。しかしそれでもまだ十分ではありません。私はこれをさらに深くし、すべてがコーシャーであることを絶対に確信させたいと思います。

だから、私はNHibernateのはString.Compareメソッドを使用することができないという例外を取得...これを行う

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

を試してみました。

普通のToLower()メソッドでこれを解決できることがわかりましたが、他の種類の比較よりも細かい粒度が必要な場合があります。

誰かがこれを回避する方法を理解するのに役立つことができますか?

答えて

3

これを行うための複数の方法がIsInsensitiveLikeで、あります

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

等Vを有します異なる比較セマンティクスを等しくすることができます。これにより、一連のセキュリティ上の問題が発生します。 –

+0

[私の答え](http://stackoverflow.com/a/31404628/11635)は非常に醜いです。ユーザー名列挙攻撃] –

1

SQL Serverのテキストマッチングは、大文字と小文字を区別しません。気に入らない場合は照合SQL_Latin1_General_CP1_CS_AS)を変更する必要があります。したがって、何か(サーバー側またはクライアント側)を変更する必要はありません。

2

デフォルトの照合および/またはspecifying an explicit oneに寄りかかっのVahidNの答え@それが動作しない場合は、1が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())); 
    } 
}