2010-07-17 8 views
3

avoir quelques problèmes pour figurer celui-ci.imbriqué sélectionnez top 1 dans Linq

select *, (sélectionner top 1 chicken_nr de chicken_photo où le poulet = code de commande par [trier]) comme photo de poulet

code

est une colonne dans le tableau poulet

Fondamentalement obtenir la photo de couverture pour cette poulet.

Pour le rendre plus clair, je veux qu'il retourne plusieurs rangées de poulet de table. Mais seulement une seule entrée de chicken_photo.

var q = from chicken in data.chickens 
        join photos in data.chicken_photos 
        on chicken.Code equals photos.chicken      
        where chicken.Lang==lang && chicken.photographer_nr == nr 
        group chicken by new  {chicken.photographer,photos.Photograph_Nr,chicken.Title,chicken.Code}    
+2

site de célibataires de poulet? –

+0

En fait, c'est pour les producteurs de poulet de faire des croisements de, donc je suppose, oui. – hreinn1000

Répondre

7

Cela peut en effet être fait de telle sorte qu'il en résulte une seule requête SQL en dessous.

Si vous effectuez la sous-sélection comme vous l'avez écrit dans Entity Framework, la requête Linq devient une requête SQL unique.

var q = from chicken in data.chickens 
      where chicken.photographer_nr == nr && chicken.Lang == lang 
      select new 
      { 
       chicken.photographer, 
       chicken.Code, 
       chicken.Title, 
       Photo = (from cp in data.chicken_photos 
         where cp.chicken == chicken.Code 
         orderby cp.Sort 
         select cp.Photograph_Nr).FirstOrDefault() 
      }; 

Si vos tables ont primaire approprié et des relations clés étrangères, et les associations de navigation appropriées dans Entity Framework, vous pouvez également obtenir les mêmes résultats de cette façon:

var q = from chicken in data.chickens 
      where chicken.photographer_nr == nr && chicken.Lang == lang 
      select new 
      { 
       chicken.photographer, 
       chicken.Code, 
       chicken.Title, 
       Photo = c.chicken_photos.Select(cp => cp.Photograph_Nr).FirstOrDefault() 
      }; 

Et enfin, pour rester complètement cohérente et utiliser uniquement les expressions lambda-:

var q = data.chickens 
     .Where(c => chicken.photographer_nr == nr && chicken.Lang == lang) 
     .Select(c => new 
      { 
       c.photographer, 
       c.Code, 
       c.Title, 
       Photo = c.chicken_photos.Select(cp => cp.Photograph_Nr).FirstOrDefault() 
      } 
     ); 

Je préfère se fondant sur la navigation de l'entité, car elle oblige le développeur à créer un bon de navigation ssociations dans Entity Framework et les relations de clés étrangères correctes dans la base de données. Cela entraînera presque toujours un SQL optimisé en dessous.

Ce n'est pas toujours au développeur de savoir comment la base de données est structurée, alors vous devrez peut-être suivre la première approche et écrire la sous-sélection vous-même.

0
var photo = (from c in chicken_photo where c.code = chicken orderby c.sort select c.chicken_nr).Take(1).SingleOrDefault(); 

Vous devriez vraiment étoffer votre question plus ...

+0

Hmm, je veux plusieurs poulets, donc j'obtiens plusieurs rangées, mais je récupère seulement une entrée de chicken_photo – hreinn1000

3

I figured it out.

en fait assez évident, trop évident :)

var q = from chicken in data.chickens 
       where chicken.photographer_nr == nr && lang == chicken.Lang 
       select new { chicken.photographer, chicken.Code, chicken.Title,Photo = (from b in data.chicken_photos where b.chicken==chicken.Code orderby b.Sort select b.Photograph_Nr).FirstOrDefault() }; 
+1

Take (1) est redondant. First() retournera la première valeur de la séquence, que cette séquence contienne une ou plusieurs valeurs. Notez qu'il lancera s'il n'y a pas de photos, utilisez FirstOrDefault() si vous voulez éviter cela. – jeroenh

+0

Merci, j'ai mis à jour la réponse pour refléter cette meilleure pratique, bien que dans mon cas les photos sont toujours peuplées – hreinn1000

+0

Je ne sais pas si c'est un bon codage, si la requête retourne 100 entrées, cela signifie 100 connexions à la base de données pour la sélection top 1 Les procédures stockées sont probablement le chemin à suivre ici. – hreinn1000

Questions connexes