2017-08-15 3 views
0

Voici mes tableaux:Pourquoi Linq-to-SQL ajoute-t-il des COUNT() inutiles?

create table customer 
(
    cid int primary key, 
    name varchar(32) 
) 

create table ord 
(
    oid int primary key, 
    cid int foreign key references customer, 
    address varchar(20) 
) 

Voici ma déclaration LINQ to SQL:

var aaa = from c in db.Customer 
      select new { c, o = c.Ord.ToList() }; 

Et voici la requête inexplicable générée par LINQ to SQL:

SELECT 
    [t0].[cid] AS [Cid], [t0].[name] AS [Name], [t1].[oid] AS [Oid], 
    [t1].[cid] AS [Cid2], [t1].[address] AS [Address], 
    (SELECT COUNT(*) 
    FROM [dbo].[ord] AS [t2] 
    WHERE [t2].[cid] = [t0].[cid]) AS [value] 
FROM [dbo].[customer] AS [t0] 
LEFT OUTER JOIN [dbo].[ord] AS [t1] ON [t1].[cid] = [t0].[cid] 
ORDER BY [t0].[cid], [t1].[oid] 

Je veux comprendre comment se débarrasser de cette partie COUNT(*). C'est entièrement dépourvu!

+1

Peut-être apparenté? https://stackoverflow.com/questions/11997048/why-does-linq-2-sql-create-extra-unnecessary-objects/12045296#12045296 – DenNukem

Répondre

1

LINQ a besoin du COUNT(*) afin de déterminer le nombre d'entrées qui seront renvoyées pour le o = c.Ord.ToList().

+0

Pourquoi y a-t-il un tel besoin? Ne pourraient-ils pas continuer à élargir la liste des choses comme elles viennent? Le problème que j'ai est que cette requête génère un plan de requête qui est N^2 où N est le nombre de commandes par client (ce qui est important dans mon cas). Je suis assez frustré avec ça. Merci pour votre perspicacité. – DenNukem

+0

Considérez comment le SQL renvoie les données - vous avez des champs 't0' (client) répétés correspondant à chaque champ' t1' (ord) dans une liste d'enregistrements. (SQL ne renvoie que les tables.) LINQ doit créer un enregistrement client fusionné avec des enregistrements n ord de cette manière. Avoir le compte disponible rend ceci beaucoup plus facile. Je ne vois pas comment cela peut être fait différemment sans interroger la base de données par client pour les enregistrements ord. Je suppose que vous utilisez Entity Framework? Que se passe-t-il si vous passez à '(à partir de c dans db.Customer sélectionnez c) .Include (" ord ")'? – NetMage

+0

C'est le linq2sql old-school, pas EF. J'imagine comme ceci: LINQ lit les enregistrements entrants, et pour chacun il créerait un nouvel objet client (s'il n'est pas créé plus tôt) et ensuite ajouterait la partie Commande de l'ensemble de résultats au client correspondant (recherché par l'ID client) . Il n'y a pas besoin de savoir combien d'Ordres vous recevez - continuez simplement à les empiler à mesure qu'ils entrent. Oh bien. – DenNukem