6
votes

Demande LINQ Donner une sortie inappropriée

J'ai deux tables de transaction nommées comme parenttransaction et enfants dans lequel transactionnement de parenttransaction agira comme étrangère à enfanttransaction de transacactionneur .

maintenant je veux obtenir tous ces transactionnements de parenttransaction dont payAmount n'est pas terminé. < P> de la sortie ci-dessous, je veux un enregistrement de transaction ID 3 car seulement 1000 a été payé pour transactionneur 3 au lieu de 5000.

J'ai une table comme celle-ci: xxx

enfanttransaction xxx

ceci est ma requête: xxx

mais ici i Obtenez une transaction ID 1 et 2 Bien que leur transaction soit terminée en deux parties de 600 et 400 pour la transaction ID 1.


0 commentaires

5 Réponses :


9
votes

Je ne suis pas sûr que ! = code> est une meilleure valeur. Voici une solution avec > code> Vérification et regroupement:

var expectedValue =
            context.ParentTransaction
                .GroupJoin(context.ChildTransaction, parent => parent.TransactionId, child => child.TransactionId, (parent, gj) => new { parent, gj })
                .SelectMany(@t => @t.gj.DefaultIfEmpty(), (@t, subset) => new { @t, subset })
                .Select(@t => new { @t, joined = new { Transaction = @t.@t.parent, Deposit = @t.subset != null ? @t.subset.Deposit : 0 } })
                .GroupBy(@t => @t.joined.Transaction, @t => @t.joined)
                .Select(grouped => new { grouped, g = new { Transaction = grouped.Key, Deposit = grouped.Sum(e => e.Deposit) } })
                .Where(@t => @t.g.Transaction.PayAmount > @t.g.Deposit)
                .Select(@t => @t.g.Transaction);


9 commentaires

pouvez-vous s'il vous plaît expliquer moi votre requête.Veuillez


Merci beaucoup monsieur pour une question géniale. J'ai vraiment eu beaucoup de mal à faire cela.Cant même merci car merci vous seriez si petit de vous remercier.


Lorsque j'ajoute 1 transaction dans la transaction parente dont l'entrée n'est pas là dans la transaction enfant, de sorte que la transaction soit impayée correctement .Pour Par exemple: Transaction ID: 4 Donc, cette transaction avec ID: 4 ne vient pas avec votre requête mise à jour.


@ Earning Oui Il y avait un problème. J'ai mis à jour ma réponse avec un exemple de joindre à gauche un lien supplémentaire vers MSDN.


Attendez-moi de tester votre requête, mais merci de mettre à jour votre réponse


Votre requête ci-dessus consiste à obtenir toutes les transactions non rémunérées.can J'utilise la même requête pour obtenir toutes les transactions payées. Je veux dire ces transactions dont le paiement complet a été effectué. Pour par exemple: transaction 1 et 2


@ Earning Bien sûr, changez simplement où expression dans votre requête à @T => @ tgtransaction.payamount == @tgdeposit ou @ tgtransaction.payamount <= @tgdeposit


Désolé, votre requête pour obtenir toutes les transactions payantes ne fonctionne pas. Je suppose que cela ne fonctionnera pas avec toutes les transactions non rémunérées. J'ai essayé celui-ci: AR attendueValue = de parent in context.parenttransaction


Belle solution orientée. OMI, lors de la création de requêtes SQL, vous obtenez de meilleurs résultats lorsque vous pensez en termes de filtrage / combinaison d'ensembles d'enregistrements, plutôt que de considérer toutes les conditions d'un seul enregistrement (si vous voyez ce que je veux dire). Et je pense que c'est plutôt optimiste de certaines personnes de penser que les optimiseurs de la requête trouveront eux-mêmes des transformations de requêtes orientées dossées dans des requêtes orientées vers lesquelles (c'est-à-dire, de changer les requêtes imbriquées à des jointures). (Mais sur ce dernier point, je suis prêt à être corrigé par quiconque bien informé.)



2
votes
List<int> obj = new List<int>();
using (DemoEntities context = new DemoEntities())
{
    obj = (from ct in context.CTransactions
    group ct by ct.Transactionid into grp
    join pt in context.PTransactions on grp.Key equals pt.Transactionid
    where grp.Sum(x => x.DepositAmount) < pt.PayAmount
    select grp.Key).ToList();
}

1 commentaires

Merci beaucoup pour vos bons efforts visant à m'aider.



2
votes

Vous ne contrôlez qu'une seule transaction enfant. Vous devez utiliser somme () opération et besoin d'utiliser > au lieu de ! = pls essayer ceci. xxx


2 commentaires

Merci beaucoup pour vos bons efforts visant à m'aider.


Pas de problème camarade. J'espère que cette réponse vous a aidé.



13
votes

L'idée générale des langues de requête est d'exprimer le résultat souhaité , pas comment l'obtenir.

l'appliquer à votre scénario conduit à une simple requête comme celle-ci xxx

si vous utilisez EF et une propriété de navigation de modèle appropriée, il serait même simple xxx

On peut dire que ce qui précède serait inefficace par rapport à la réponse de @vadim Martynov Répondre. Eh bien, peut être oui, peut ne pas être. Vadim tente de forcer un plan d'exécution spécifique et je peux comprendre cela - nous devons faire des choses telles que dans la réalité rencontrant des problèmes de performance de la requête. Mais ce n'est pas naturel et devrait être un dernier recours que si nous avons des problèmes de performance. Les fournisseurs de requêtes et les optimiseurs de requête SQL feront (et font) que le travail pour nous dans la plupart des cas dans la plupart des cas, nous n'avons donc pas besoin de penser si nous devons utiliser un joindre vs sous-requête etc.


9 commentaires

pouvez-vous me montrer une requête équivalente SQL pour cela s'il vous plaît


@Learning Ajouter var sql = Query.tostring (); , exécutez VS débogueur, mettez un point d'arrêt et examinez SQL variable dans les locaux / fenêtre de surveillance avec le texte Visualizer.


avez-vous regardé Vadim Query.can tu me dites quelque chose à ce sujet parce que je n'ai pas compris quoi que ce soit dans sa requête


Oui je l'ai fait. C'est une façon correcte et alternative de produire le même résultat. Mais c'est le point principal de mon post, en regardant la requête, il est difficile de comprendre ce qu'il fait. Vous pouvez utiliser la documentation IntelliSense et MSDN pour le comprendre, mais il crée fondamentalement une substitution qui regroupe les transactions enfants par trasactionid et calcule la somme du debitamout , puis joint cette sous-requête à < Code> Parenttransaction Table pour obtenir le résultat final.


oui sa requête est correcte mais vraiment difficile de comprendre ce qu'il fait est sa requête


Dans votre requête Comment puis-je sélectionner des fieilds de ma table parenttransaction?


La façon dont j'ai écrit, il renvoie tous les champs de la table parenttransaction , c'est pourquoi aucune sélection spéciale n'est nécessaire.


Je parle de votre première requête


Laissez-nous Continuez cette discussion en chat .



4
votes

Problème

Le problème réside sur cet énoncé: p> xxx pré>

et puisque le TMP1 code> est défini comme un single Strong> Transaction des enfants, la déclaration entraînerait d'assimiler des valeurs incorrectes: p>

Visualizer strong>: p> xxx pré>

mais ce que vous voulez avoir plutôt: p>

Visualizer strud>: p> xxx pré>

Ainsi, vous devez faire TMP1 code> est comme une collection forte> d'enfants plutôt que unique forte> enfant p>


solution h2>

transaction non rémunérée h3>

Changez votre code comme celui-ci: p> xxx pré>


explications forte> p>

Cette ligne: p>

var grp = context.ChildTransaction.GroupBy(y => y.TransactionId);
var data = (from tmp in context.ParentTransaction
            join tmp1 in grp //group this by transaction id
            on tmp.TransactionId equals tmp1.Key //use the key
            where tmp.PayAmount > tmp1.Sum(x => x.DepositAmount)
            select tmp)
            .Union((
            from tmp in context.ParentTransaction
            where !context.ChildTransaction.Select(x => x.TransactionId).Contains(tmp.TransactionId)
            select tmp));

var datapaid = (from tmp in context.ParentTransaction
                join tmp1 in grp
                on tmp.TransactionId equals tmp1.Key
                where tmp.PayAmount <= tmp1.Sum(x => x.DepositAmount)
                select tmp);


6 commentaires

Pouvez-vous me dire quelle est la différence entre la requête de votre requête et D mayuri comme parce que j'ai déjà essayé d de la requête Mayuri qui ne fonctionne pas


@ Earning je n'ai pas essayé D. Mayuri. Mais j'ai essayé ma propre requête et ça marche bien. Donnez-moi un moment, je l'essayerais. Et pendant ce temps, vous pourriez aussi essayer le mien ...


Ouais, je vais certainement essayer votre requête, mais s'il vous plaît considérer les cas que j'ai décrits sur Vadim Answers.Voir mes commentaires sur Vadim Répondre


@ Earning Aah, je vois. Vous voulez aussi obtenir la transaction 4 qui n'a pas de paye du tout ... je vais mettre à jour ma réponse ..


Je veux juste obtenir toute transaction non rémunérée.


Laissez-nous Continuez cette discussion en chat .