2010-04-14 4 views
2

Pour une colonne de type varchar Je pourrais écrire cette requête de recherche:requête Comme pour DateTime dans NHibernate

public IList<Order> GetByName(string orderName) 
{ 
using (ISession session = NHibernateHelper.OpenSession()) 
{ 
    return session.CreateCriteria<Order>(). 
    Add(Restrictions.Like("Name", string.Format("%{0}%", orderName))). 
    List<Order>(); 
} 
} 

Comment implémenter la requête de recherche similaire pour une colonne qui a un type DateTime?

public IList<Order> GetByDateTime(string str) 
{ 
    using (ISession session = NHibernateHelper.OpenSession()) 
    { 
     return session.CreateCriteria<Order>() 
      .Add(Restrictions.Like(Projections.Cast(NHibernateUtil.String, Projections.Property("Created")), 
            '%' + str + '%')) 
      .List<Order>(); 
    } 
} 

C'est, si la méthode est passée la date et à temps partiel (par exemple « 25.03.2010 19 »), affiche alors toutes les commandes sont effectuées dans cette période:
25.03.2010 19 : 22: 00
25.03.2010 19:44:00
25.03.2010 19:59:00

+0

NHibernate ne peut rien faire qui ne peut être fait en sql, donc vous devez créer votre propre fonction d'analyse de date en C# comme Aaronaught suggère – Paco

Répondre

3

juste vérifier si la date est comprise dans la gamme souhaitée:

DateTime beginDate = new DateTime(2010, 3, 25, 19, 0, 0); 
DateTime endDate = new DateTime(2010, 3, 25, 20, 0, 0); 
return session.CreateCriteria<Order>() 
    .Add(Expression.Between("OrderDate", beginDate, endDate)) 
    .List<Order>(); 
+0

Votre réponse est compréhensible et logique. Mais ... L'utilisateur spécifie seulement la chaîne de date comme "14.04.2010", "2010", "14.04", "04.2010 22:06", etc. – akrisanov

+0

@Anry: Si '2010' et' 14.04' sont tous les deux valides entrées, comment désambiguïs-tu? '14.04' pourrait signifier le 14 avril, ou pourrait signifier avril 2014. Ou cela pourrait signifier 14:04. Que faire si l'entrée est juste '10', devrait-on interpréter cela comme 2010 ou Octobre? La solution la plus simple consisterait à demander à l'utilisateur une plage de dates au lieu d'une entrée de texte arbitraire. La solution la plus conviviale, mais exponentiellement la plus difficile consiste à analyser la date floue dans une plage utilisable en utilisant l'arithmétique des dates et éventuellement quelques expressions régulières. – Aaronaught

0

J'ai eu un semblable pr oblem en utilisant LINQ et l'a fixé à l'aide de la réponse postée par vikram nayak sur la question posée ici: Nhibernate LINQ DateTime.AddDay does not work.

Voilà comment je l'ai fait:
Je remplacé les classes dans l'exemple de Vikram suivantes:

public class ExtendedLinqtoHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry 
{ 
    public ExtendedLinqtoHqlGeneratorsRegistry() 
    { 
     this.Merge(new DateTimeToShortDateStringGenerator()); 
     //I had to use the lines below instead. 
     //MethodInfo method = ReflectionHelper.GetMethodDefinition<DateTime>(x => x.ToShortDateString()); 
     //RegisterGenerator(method, new DateTimeToShortDateStringGenerator()); 
    } 
} 

public class DateTimeToShortDateStringGenerator : BaseHqlGeneratorForMethod 
{ 
    public DateTimeToShortDateStringGenerator() 
    { 
     SupportedMethods = new[] 
     { 
      ReflectionHelper.GetMethodDefinition<DateTime>(x => x.ToShortDateString()) 
     }; 
    } 

    public override HqlTreeNode BuildHql(MethodInfo method, System.Linq.Expressions.Expression targetObject, ReadOnlyCollection<System.Linq.Expressions.Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) 
    { 
     return treeBuilder.MethodCall("DateTimeToShortDateString", visitor.Visit(targetObject).AsExpression()); 
    } 
} 

public class CustomDialect : MsSql2008Dialect 
{ 
    public CustomDialect() 
    { 
     RegisterFunction(
      "DateTimeToShortDateString", 
      new SQLFunctionTemplate(
      NHibernateUtil.DateTime, 
      "CONVERT(NVARCHAR(10), ?1, 105)" 
      ) 
     ); 
    } 
} 

Vous pouvez ensuite utiliser la syntaxe suivante:

using (session.BeginTransaction()) 
{ 
    var patients = session.Query().Where(p => p.BirthDate.ToShortDateString().Contains("1975")); 
}
Questions connexes