2010-03-05 2 views
4

Je veux créer l'instruction T-SQL suivante:Comment utiliser ICriteria NHibernate pour le regroupement, les associations et les fonctions allant chercher T-SQL

SELECT SUM (sa.Amount) as 'SumAmount', 
     SUM(sa.Cost) as 'SumCost', 
     gg.[Description] as 'Goodsgroup', Month(sa.[Date]) as 'Month' 
FROM SalesmanArticle sa 
INNER JOIN Article a 
    ON a.ArticleId = sa.ArticleId 
INNER JOIN GoodsGroup gg 
    ON gg.GoodsGroupId = a.GoodsGroupId 
GROUP BY gg.[Description], Month(sa.[Date]) 
ORDER BY 'Month', 'Goodsgroup' 

Est-ce possible avec NHibernates ICriteria? Comment utiliser la fonction mois-T-SQL?

Comment utiliser la fonction Month-T-SQL?

Dois-je joindre manuellement ou l'API ICriteria sait-elle que lorsque j'utilise le nom de propriété 'SalesmanArticle.Article.Goodsgroup.Description', elle doit rejoindre l'article et le groupe de marchandises?

EDIT:

Pour l'instant j'ai écrit ce code ici:

// typesafe properties 
string article = typeof(Article).Name; 
string goodsGroup = typeof(GoodsGroup).Name; 
string salesmanArticle = typeof(SalesmanArticle).Name; 

string amount = Reflector.GetPropertyName<SalesmanArticle>(x => x.Amount); 
string cost = Reflector.GetPropertyName<SalesmanArticle>(x => x.Cost); 
string description = string.Format("{0}.{1}", 
    goodsGroup, Reflector.GetPropertyName<SalesmanArticle>(x => x.Article.GoodsGroup.Description)); 
string date = Reflector.GetPropertyName<SalesmanArticle>(x => x.Date); 

string formatedDate = string.Format("MONTH([{0}])", date); 

return GetSession() 
    // FROM 
    .CreateCriteria(typeof(SalesmanArticle), salesmanArticle) 
    // JOIN 
     .CreateCriteria(article, article, JoinType.InnerJoin) 
     .CreateCriteria(goodsGroup, goodsGroup, JoinType.InnerJoin) 
    // SELECT 
     .SetProjection(Projections.ProjectionList() 
          .Add(Projections.Sum(amount)) 
          .Add(Projections.Sum(cost)) 
    // GROUP BY 
          .Add(Projections.GroupProperty(description)) 
          .Add(Projections.SqlGroupProjection(formatedDate, formatedDate, new[]{"MyDate"} , new[] { NHibernateUtil.Int32 }))) 
     .List(); 

Mais un AdoException est jeté:

ne pouvait pas exécuter la requête [SELECT somme (this_.Amount) comme y0_, sum (this_.Cost) comme y1_, goodsgroup2_.Description comme y2_, MOIS ([Date]) FROM [SalesmanArticle] this_ jointure interne [article] article1_ sur this_.ArticleId = article1_.ArticleId jointure [GoodsGroup] goodsgroup2_ sur article1_.GoodsGroupId = goodsgroup2_.GoodsGroupId GROUP BY goodsgroup2_.Description, MOIS ([Date])]

[SQL: SELECT somme (this_.Amount) comme y0_, somme (this_.Cost) comme y1_, goodsgroup2_.Description comme y2_, MOIS ([date]) FROM [SalesmanArticle] this_ jointure interne [ Article] article1_ sur this_.ArticleId = article1_.ArticleId jointure interne [G oodsGroup] goodsgroup2_ sur article1_.GoodsGroupId = goodsgroup2_.GoodsGroupId GROUP BY goodsgroup2_.Description, MOIS ([Date])]

La chose étrange est que NHibernate essaie de créer 2 requêtes ?!

ET les deux sont corrects!

Au lieu de la ligne de code

.Add(Projections.SqlGroupProjection(formatedDate, formatedDate, new[]{"MyDate"} , new[] { NHibernateUtil.Int32 }))) 

J'utilisé

.Add(Projections.SqlFunction("MONTH", NHibernateUtil.Int32, Projections.GroupProperty(date)))) 

Le problème avec le SqlFunction est qu'il crée un GROUP BY sa.Date au lieu de MOIS (sa.Date). Mais cette méthode a fonctionné syntaxiquement correcte. J'ai donc passé à la méthode SqlGroupProjection.

Mais de toute façon cela ne fonctionne pas.

Quelqu'un peut-il m'aider?

Répondre

6

Je l'ai résolu.Voici le code correct:

public class SalesmanArticleRepository : Repository<SalesmanArticle>, ISalesmanArticleRepository 
{ 
    public IList GetAllAll() 
    { 
     // typesafe properties 
     string article = typeof(Article).Name; 
     string goodsGroup = typeof(GoodsGroup).Name; 
     string salesmanArticle = typeof(SalesmanArticle).Name; 

     string amount = Reflector.GetPropertyName<SalesmanArticle>(x => x.Amount); 
     string cost = Reflector.GetPropertyName<SalesmanArticle>(x => x.Cost); 
     string description = string.Format("{0}.{1}", 
      goodsGroup, Reflector.GetPropertyName<SalesmanArticle>(x => x.Article.GoodsGroup.Description)); 
     string date = Reflector.GetPropertyName<SalesmanArticle>(x => x.Date); 

     string formatedDateSql = string.Format("month({{alias}}.[{0}]) as mydate", date); 
     string formatedDateGroupBy = string.Format("month({{alias}}.[{0}])", date); 

     return GetSession() 
      // FROM 
      .CreateCriteria(typeof(SalesmanArticle), salesmanArticle) 
      // JOIN 
       .CreateCriteria(article, article, JoinType.InnerJoin) 
       .CreateCriteria(goodsGroup, goodsGroup, JoinType.InnerJoin) 
      // SELECT 
       .SetProjection(Projections.ProjectionList() 
            .Add(Projections.Sum(amount)) 
            .Add(Projections.Sum(cost)) 
      // GROUP BY 
            .Add(Projections.GroupProperty(description)) 
            .Add(Projections.SqlGroupProjection(formatedDateSql, formatedDateGroupBy, new[] { "mydate" }, new[] { NHibernateUtil.Int32 }))) 
       .List(); 
    } 
} 
+0

Savez-vous comment le faire en hql? J'aime Hql –

Questions connexes