2012-06-06 12 views
6

Me gustaría buscar todos los registros de un día determinado, sin importar la hora asociada con esos registros. Hasta ahora tengo método como este:Obteniendo registros por fecha con solo comparación de partes de día usando 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); 
    } 

Pero en LINQ a objetos que podemos hacer (suponiendo que la tabla es ahora parte de la recopilación):

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

que obviamente es más fácil de leer y se siente más limpio . Me preguntaba si hay una mejor manera de escribir el primer método usando el almacenamiento de la base de datos y nhibernate.

+0

Creo que la forma que utilizó para L2O funciona bien con NH. –

+0

@Diego Mijelshon ¿Puede decirme qué versión de NHibernate está utilizando que funciona? En el proyecto en el que estoy trabajando utilizamos v. 2.1 y esto arroja NHibernate.QueryException. – 0lukasz0

+1

2.1 tiene 3 años y no es compatible. 3.3 es la versión estable actual. –

Respuesta

6

Como se ha dicho en los comentarios, la consulta LINQ funciona bien con NH 3.3.

En versiones anteriores, se puede usar HQL:

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

También puede utilizar la función date de Criteria, a través de SqlFunction. Esto es más intrincado, pero permite crear consultas más dinámicas:

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

¿Puede decirme qué versión de NHibernate está utilizando que funciona? En el proyecto en el que estoy trabajando utilizamos v. 2.1 y esto arroja NHibernate.QueryException. – 0lukasz0

+1

¡Oh! v2.1 no admite Linq pero hay una rama con el proveedor de Linq, una que no funcionó. La versión 3+ incluye un proveedor nativo de Linq. Como señaló @Diego Mihelshon, "2.1 tiene 3 años y no es compatible. 3.3 es el lanzamiento estable actual". – ivowiblo

+0

Ok, doy este +1 aunque si SomeDateAttr.Date == OtherDate.Date funciona en NH 3+ entonces es un mejor enfoque en mi opinión. – 0lukasz0

2

Depende del proveedor de LINQ. No estoy seguro de si el proveedor NHibernate LINQ es compatible con la sintaxis item.SomeDateProperty.Date == x y dudo que lo haga. Sin embargo, usted puede hacer su propio método de extensión de este 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))); 

} 

esto no se va a construir la forma en que es ahora - Yo sólo estaba tratando de darle una idea de qué hacer.

entonces Se puede utilizar de este modo:

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

+1, me gusta la idea, aunque parece más actualizada NHibernate es compatible con las soluciones más fáciles. – 0lukasz0

Cuestiones relacionadas