2011-04-04 5 views
0

Je cette requête SQL:LINQ et comparaison de requête SQL

SELECT Sum(ABS([Minimum Installment])) AS SumOfMonthlyPayments FROM tblAccount 
INNER JOIN tblAccountOwner ON tblAccount.[Creditor Registry ID] = tblAccountOwner. 
[Creditor Registry ID] AND tblAccount.[Account No] = tblAccountOwner.[Account No] 
WHERE (tblAccountOwner.[Account Owner Registry ID] = 731752693037116688) 
AND (tblAccount.[Account Type] NOT IN 
('CA00', 'CA01', 'CA03', 'CA04', 'CA02', 'PA00', 'PA01', 'PA02', 'PA03', 'PA04')) 
AND (DATEDIFF(mm, tblAccount.[State Change Date], GETDATE()) <= 
4 OR tblAccount.[State Change Date] IS NULL) 
AND ((tblAccount.[Account Type] IN ('CL10','CL11','PL10','PL11')) OR 
CONTAINS(tblAccount.[Account Type], 'Mortgage')) AND (tblAccount.[Account Status ID] <> 999) 

J'ai créé une requête Linq:

var ownerRegistryId = 731752693037116688; 
var excludeTypes = new[] 
{ 
    "CA00", "CA01", "CA03", "CA04", "CA02", 
    "PA00", "PA01", "PA02", "PA03", "PA04" 
}; 

var maxStateChangeMonth = 4; 
var excludeStatusId = 999; 
var includeMortgage = new[] { "CL10", "CL11", "PL10", "PL11" }; 

var sum = (
    from account in context.Accounts 
    from owner in account.AccountOwners 
    where owner.AccountOwnerRegistryId == ownerRegistryId 
    where !excludeTypes.Contains(account.AccountType) 
    where account.StateChangeDate == null || 
     (account.StateChangeDate.Month - DateTime.Now.Month) 
      <= maxStateChangeMonth 
    where includeMortgage.Contains(account.AccountType) || 
     account.AccountType.Contains("Mortgage") 
    where account.AccountStatusId != excludeStatusId 
    select account.MinimumInstallment).ToList() 
    .Sum(minimumInstallment => 
     Math.Abs((decimal)(minimumInstallment))); 

return sum; 

Sont-ils égaux/même? Je n'ai pas d'enregistrements en db donc je ne peux pas confirmer si elles sont égales. En SQL il y a des parenthèses() mais dans Linq je ne les ai pas utilisées donc est-ce correct?

Veuillez nous suggérer.

Répondre

1

Il ne nous est pas possible de dire quoi que ce soit à ce sujet, parce que vous ne nous avez pas montré le DBML. La définition réelle du mappage entre le modèle et la base de données est importante pour pouvoir voir comment cela s'exécute.

Mais avant d'ajouter le DBML à votre question: nous ne sommes pas ici pour faire votre travail, alors voici deux conseils pour savoir si elles sont égales ou non:

  1. Insérez des données dans votre base de données et exécuter les requêtes.
  2. Utilisez un profileur SQL et voyez quelle requête est exécutée par votre fournisseur LINQ sous les couvertures.

Si vous avez quelque chose de plus spécifique à demander, nous serons très disposés à vous aider.

+0

Salut Steven: Je veux juste savoir que si j'ai traduit le SQL correctement? – DotnetSparrow

+0

@DotnetSparrow: Je sais que tu veux, mais comme je l'ai dit dans ma réponse: on ne peut pas te le dire car il manque des informations, et même s'il n'y en avait pas: l'extrait de code est trop gros. Vous devrez le comprendre vous-même. J'espère que mes conseils et ceux des autres vous aideront à trouver une réponse à votre question. – Steven

1

Les parenthèses seront générées par le fournisseur LINQ, si nécessaire.
La manière la plus simple de vérifier si la requête LINQ est égale à la requête SQL initiale est de la journaliser comme suggéré par @Atanas Korchev.
Si vous utilisez Entity Framework, cependant, il n'y a pas la propriété du journal, mais vous pouvez essayer de convertir votre requête à un ObjectQuery et appeler la méthode ToTraceString alors:
string sqlQuery = (sum as ObjectQuery).ToTraceString();
UPD. La méthode ToTraceString nécessite une instance ObjectQuery pour le suivi, et l'appel ToList() effectue déjà la matérialisation, donc il n'y a rien à tracer. Voici le code mis à jour:

var sum = (
from account in context.Accounts 
from owner in account.AccountOwners 
where owner.AccountOwnerRegistryId == ownerRegistryId 
where !excludeTypes.Contains(account.AccountType) 
where account.StateChangeDate == null || 
    (account.StateChangeDate.Month - DateTime.Now.Month) 
     <= maxStateChangeMonth 
where includeMortgage.Contains(account.AccountType) || 
    account.AccountType.Contains("Mortgage") 
where account.AccountStatusId != excludeStatusId 
select account.MinimumInstallment); 
string sqlQuery = (sum as ObjectQuery).ToTraceString(); 

S'il vous plaît noter que ce code ne fonctionnera pas la requête réelle, il est utilisable uniquement à des fins de test. Découvrez this article si vous êtes intéressé par l'implémentation de la journalisation prête à la production.

+0

et @Atanas: Je travaille dans l'application MVC afin que la trace soit disponible là ou context.log peut être consulté? – DotnetSparrow

+0

Bonjour @Devart: J'ai eu cette erreur quand j'ai utilisé TraceString: Impossible de convertir le type 'decimal' en 'System.Data.Objects.ObjectQuery' via une conversion de référence, une conversion boxing, une conversion unboxing, une conversion wrapping, ou une conversion de type null – DotnetSparrow

+0

@ DotnetSparrow, jetez un oeil à la mise à jour. – Devart

0

Il peut y avoir une différence de performance:

La requête SQL retourne un seul numéro (SELECT Sum...) directement à partir du serveur de base de données au client qui exécute la requête.

Dans votre requête LINQ vous avez un opérateur avide (.ToList()) entre:

var sum = (... 
    ... 
    select account.MinimumInstallment).ToList() 
    .Sum(minimumInstallment => 
     Math.Abs((decimal)(minimumInstallment))); 

Cela signifie que la requête sur le serveur SQL ne contient pas l'opération .Sum. La requête renvoie une liste (potentiellement longue?) De MinimumInstallments. Ensuite, l'opération .Sum est effectuée en mémoire sur le client.

Donc, vous passez effectivement de LINQ aux entités à LINQ to Objects après .ToList().

BTW: Pouvez-vous vérifier la dernière proposition dans votre previous question here qui permettrait d'éviter .ToList() sur cette requête (si la proposition devrait fonctionner) et serait donc plus proche de l'instruction SQL.

+0

@Saluma: J'ai essayé cela mais je recevais toujours la même erreur donc j'ai utilisé tolist et c'est parti. – DotnetSparrow

+0

@DotnetSparrow: Je vois, il y a un nouveau Modifier dans la question précédente. – Slauma