2012-06-06 7 views
6

Desidero recuperare tutti i record da un giorno particolare, indipendentemente dall'orario associato a tali record. Finora ho metodo come questo:Recupero dei record per data con confronto solo per il componente diurno con nibernato

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

Ma in LINQ-to-oggetto che possiamo fare (ammesso tabella è ora un po 'di raccolta):

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

che ovviamente è più leggibile e si sente più pulita . Mi stavo chiedendo se c'è un modo migliore per scrivere il primo metodo utilizzando la memoria del database e l'inibizione?

+0

Credo che il modulo utilizzato per L2O funziona bene con NH. –

+0

@Diego Mijelshon Puoi dirmi quale versione di NHibernate stai usando che funziona? Al progetto a cui sto lavorando stiamo usando v. 2.1 e questo sta lanciando NHibernate.QueryException. – 0lukasz0

+1

2.1 ha 3 anni e non è supportato. 3.3 è l'attuale versione stabile. –

risposta

6

Come detto nei commenti, la query LINQ funziona bene con NH 3.3.

Nelle versioni precedenti, è possibile utilizzare HQL:

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

È anche possibile utilizzare la funzione date da criteri, via SqlFunction. Questo è più complicata, ma permette di costruire query più dinamici:

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

Puoi dirmi quale versione di NHibernate stai usando che funziona? Al progetto a cui sto lavorando stiamo usando v. 2.1 e questo sta lanciando NHibernate.QueryException. – 0lukasz0

+1

Oh! v2.1 non supporta Linq ma c'è un ramo con il provider Linq, uno che non ha funzionato. La versione 3+ include un fornitore Linq nativo. Come ha sottolineato @Diego Mihelshon, "2.1 ha 3 anni e non è supportato, 3.3 è l'attuale versione stabile." – ivowiblo

+0

Ok, ho dato questo +1 anche se SomeDateAttr.Date == OtherDate.Date funziona in NH 3+, quindi è un approccio migliore secondo me. – 0lukasz0

2

Dipende dal provider LINQ. Non sono sicuro che il provider LINQ di NHibernate supporti la sintassi item.SomeDateProperty.Date == x e sono dubbioso. Ma, è possibile rendere il proprio metodo di estensione in questo modo:

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

} 

questo non sta andando a costruire il senso che è ora - Stavo solo cercando di dare un'idea di cosa fare.

È quindi possibile utilizzare in questo modo:

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

+1, mi piace l'idea, anche se sembra più aggiornata NHibernate supporta le soluzioni più semplici. – 0lukasz0