2012-06-06 6 views
6

Ich möchte alle Datensätze von bestimmten Tag abrufen, egal welche Zeit mit diesen Datensätzen verbunden ist. Bisher habe ich Methode wie folgt:Abrufen von Datensätzen nach Datum mit nur Tag Teil Vergleich mit Nhibernate

public IQueryable<Record> QueryByDay(DateTime day) 
{ 
    DateTime from = day.Date; 
    DateTime to = day.Date.AddDays(1); 

    return repository.Table 
     .Where(t => t.MyDate >= from && t.MyDate < to); 
    } 

Aber in Linq-zu-Objekt, das wir tun können (vorausgesetzt Tabelle ist jetzt einige Sammlung):

public IEnumerable<Record> QueryByDay(DateTime day) 
{ 
    return repository.Table 
     .Where(t => t.MyDate.Date == day.Date); 
} 

, die offensichtlich besser lesbar ist und fühlt sich mehr sauber . Ich frage mich, ob es eine bessere Möglichkeit gibt, die erste Methode mit Datenbankspeicher und Nhibernate zu schreiben?

+0

Ich glaube, die Form, die Sie für L2O verwendet haben, funktioniert gut mit NH. –

+0

@Diego Mijelshon Können Sie mir sagen, welche Version von NHibernate Sie verwenden, dass es funktioniert? Bei dem Projekt, an dem ich arbeite, verwenden wir Version 2.1 und werfen NHibernate.QueryException. – 0lukasz0

+1

2.1 ist 3 Jahre alt und nicht unterstützt. 3.3 ist die aktuelle stabile Version. –

Antwort

6

Wie gesagt in den Kommentaren, Ihre LINQ-Abfrage mit NH 3.3 funktioniert gut.

In früheren Versionen können Sie HQL verwenden:

return session.CreateQuery("from MyClass where date(MyDate) = :day") 
       .SetParameter("day", day.Date) 
       .List<MyClass>(); //executes 

Sie können auch die date Funktion von Kriterien, über SqlFunction verwenden. Dies ist komplizierter, aber ermöglicht dynamischere Abfragen:

return session.CreateCriteria<Foo>() 
       .Add(Restrictions.Eq(
         Projections.SqlFunction("date", 
               NHibernateUtil.Date, 
               Projections.Property("MyDate")), 
         day.Date)) 
       .List<MyClass>(); //executes 
2
public IEnumerable<Record> QueryByDay(DateTime day) 
{ 
    return repository.Table 
     .Where(t => t.MyDate.Day == day.Day && t.MyDate.Month == day.Month && t.MyDate.Year == day.Year); 
} 
+0

Können Sie mir sagen, welche Version von NHibernate Sie verwenden, dass es funktioniert? Bei dem Projekt, an dem ich arbeite, verwenden wir Version 2.1 und werfen NHibernate.QueryException. – 0lukasz0

+1

Oh! v2.1 unterstützt Linq nicht, aber es gibt eine Verzweigung mit dem Linq-Provider, eine, die nicht geklappt hat. Version 3+ enthält einen nativen Linq-Provider. @Diego Mihelshon wies darauf hin: "2.1 ist 3 Jahre alt und nicht unterstützt. 3.3 ist die aktuelle stabile Veröffentlichung." – ivowiblo

+0

Ok, ich gebe diese +1 wenn SomeDateAttr.Date == OtherDate.Date funktioniert in NH 3+ dann ist es besser Ansatz meiner Meinung nach. – 0lukasz0

2

Es hängt vom LINQ-Anbieter ab. Ich bin nicht sicher, ob NHibernate LINQ Provider die item.SomeDateProperty.Date == x Syntax unterstützt und ich bin zweifelhaft, ob es tut. Aber können Sie Ihre eigene Erweiterungsmethode wie so machen:

public static IQueryable<T> FilterByDate(this IQueryable<T> This, Expression<Func<T, DateTime>> getProperty, DateTime date) 
{ 
    DateTime from = day.Date; 
    DateTime to = day.Date.AddDays(1); 
    return This.Where(x=> 
    Expression.And(
     Expression.GreaterThan(getProperty, Expression.Variable(from)), 
     Expression.LessThan(getProperty, Expression.Variable(to))); 

} 

Dies ist nicht die Art und Weise gehen zu bauen ist es jetzt - ich habe nur versucht, Ihnen eine Vorstellung zu geben, was zu tun ist.

Sie können es dann wie so verwenden:

var result = repository.Table.FilterByDate(x=>x.MyDate, new DateTime(2012, 6,6)); 
+0

+1, Ich mag die Idee, obwohl sieht wie aktueller NHibernate unterstützt einfachste Lösungen. – 0lukasz0

Verwandte Themen