6 Stimmen

Zeichenfolgen können bei nHibernate QueryOver<T> nicht verglichen werden

Ich habe eine einfache Methode, um zu versuchen und Benutzer zu validieren, wenn sie sich anmelden, und ich verwende Fluent nHibernate für die Persistenz, also implementiere ich natürlich eine ISession.QueryOver<T> um diese Arbeit zu erledigen.

Sie sieht folgendermaßen aus.

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

Ok. Nun zu den anstehenden Problemen.

  1. Bei E-Mail-Adressen ist die Groß- und Kleinschreibung nicht zu beachten.

Sie sollte in der Datenbank immer in Kleinbuchstaben erscheinen. Ich habe mir große Mühe gegeben, dies zu erreichen. Und in der Tat, mein <input> die die Email Address hat eine Validierungsregel, die nur Kleinbuchstaben zulässt. Aber das ist immer noch nicht gut genug. Ich möchte das Ganze noch weiter vertiefen und absolut sicherstellen, dass alles koscher ist.

Also habe ich versucht, dies zu tun...

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

Ich erhalte eine Ausnahme, dass nhibernate nicht die String.Compare Methode.

Mir ist klar, dass ich das Problem auch mit der einfachen ToLower() Methode, aber es kann Situationen geben, in denen ich ein wenig mehr Granularität über andere Arten von Vergleichen wünsche.

Kann mir jemand sagen, wie ich das umgehen kann?

4voto

Peter Punkte 26984

Es gibt mehrere Möglichkeiten, dies zu tun, mit einem IsInsensitiveLike:

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

3voto

Ruben Bartelink Punkte 57310

Wenn die Antwort von @VahidN, sich auf die Standardsortierung zu stützen und/oder eine explizite Angabe zu machen nicht funktioniert, kann man auf die SQL-Dialekt-spezifische Groß-/Kleinschreibungskonvertierung wie folgt zurückgreifen:

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

Wird wie folgt umgesetzt:

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()));
    }
}

1voto

VahidN Punkte 17078

SQL Server Text Matching ist Case INSENSITIVE. Wenn Ihnen das nicht gefällt, müssen Sie die Kollation ( SQL_Latin1_Allgemein_CP1_CS_AS ). Sie brauchen also nichts zu ändern (weder serverseitig noch clientseitig).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X