11
votes

Renvoyez plusieurs colonnes d'agrégats à Linq

Je voudrais traduire le SQL suivant en linq: xxx

J'ai essayé ceci: xxx

mais obtenir une erreur "Les offres ne contiennent pas de définition de" somme "et aucune méthode d'extension" somme "acceptant un premier argument de type" offres ".

Comment puis-je faire cela à Linq?

merci

conclus:

La réponse finale était la suivante: xxx


0 commentaires

4 Réponses :


8
votes

Vous pouvez essayer cela. La variable B est une entité (pour chaque itération) tandis que CTX est une entité d'entrée qui dispose des méthodes d'extension dont vous avez besoin.

var ctx = _dataContext.Bids;

var result = ctx
    .Select( x => new
    {
        TotalBidVal = ctx.Sum  ( p => p.Amount ),
        TotalBidNum = ctx.Count( p => p.BidId  )
    } )
    .First();


4 commentaires

Cela a résolu l'erreur (bien que cela semble être une étape inutile - pourquoi est-ce nécessaire?). Il y avait un problème avec mon compte (p => p.bidid) - une erreur que p.bidid n'était pas booléen. Je l'ai remplacé par Count () et maintenant la requête renvoie la somme correcte et compter mais pas comme une seule ligne. La même rangée sur et sur la fois - je présume autant de fois que de lignes dans la table des offres. Comment puis-je retourner une seule ligne comme dans ma requête SQL d'origine?


@BKAHUNA Votre requête dit "de b in _datacontext.bids" c'est une itération. Et vous n'obtiendrez pas un résultat même si vous essayez de calculer juste la somme et le compte. Vous pouvez mettre fin à l'expression Lambda en appelant d'abord (). qui ne vous donnera qu'un seul résultat que j'ai fait.


@Bkahuna S'il vous plaît faire défiler ma réponse à la fin et voir le dernier appel que je fais. J'appelle la première méthode () qui garantira que je n'obtiens qu'une ligne de retour (le SQL généré est le top (1))


Quand je fais cela, je reçois un jointure croisée croix très inefficace requête SQL. J'ai besoin d'utiliser le groupby (x => 1) astuce pour obtenir une requête efficace.



1
votes

Voici une alternative à la solution de SCARTAG:

var result = new 
{
    TotalBidVal = _dataContext.Bids.Sum(p => p.Amount), 
    TotalBidNum = _dataContext.Bids.Count()
};


0 commentaires

22
votes

Vous pouvez écrire cette requête en utilisant groupby code>. L'expression Lambda est la suivante:

    var itemsBid = db.Bids
                     .GroupBy( i => 1)
                     .Select( g => new
                     {
                          TotalBidVal = g.Sum(item => item.Amount), 
                          TotalBidNum = g.Count(item => item.BidId)
                     });


5 commentaires

Exactement ce dont j'avais besoin (bien que dans l'ancienne Linq, sans linq2sql ou ef).


C'est simple mais fait l'affaire. Au fait, j'aimerais connaître le but de l'opérateur ".groupby (i => 1)". Pourquoi avons-nous besoin de cela?


Comment savons-nous que les fonctions d'agrégat ( somme , comptent ) sont calculées dans une itération? Ne pourrait-il pas être itération du groupe deux fois pour cela? (qui est quelque chose que je veux éviter)


@ Thomas.benz que l'expression regroupe la ierérable par une constante, de sorte que tous les éléments de la italienne se retrouvent dans un seul groupe. Normalement avec GroupBy, vous fournissez une fonction pour que les éléments soient mis en plusieurs groupes différents.


@Miguel Merci pour votre explication utile.



0
votes

Vous pouvez le faire en utilisant le clause globale .

Aggregate t In _dataContext.Bids.AsParallel


0 commentaires