2017-10-20 62 views
1

Dire que j'aurais la structure de base de données suivante: database structurefaçon Performant pour aller chercher toutes les lignes à l'intérieur et parent extérieur enregistrement

Et je voulais obtenir tous les enregistrements de ligne qui sont dans une page.

Les PageItems Table contient soit une valeur LineID ou une ParagraphId valeur pour chaque enregistrement.

page

 
Id Title 
----------- 
1 My page 

PageItems

 
PageId LineId ParagraphId 
------------------------- 
1  1  NULL 
1  2  NULL 
1  NULL 1 

Paragraphe

 
Id 
-- 
1 

ParagraphItems

 
ParagraphId LineId 
------------------ 
1   3 
1   4 

Ligne

 
Id Content 
------------------ 
1 Loose line 1 
2 Loose line 2 
3 Paragraph line 1 
4 Paragraph line 2 

Ma première pensée utilisait UNION, mais étant donné que ce sont des grandes tables qui ne seraient pas bien. Donc, je suis à la recherche d'une solution de requête unique sur laquelle je peux filtrer après avoir sélectionné les lignes.

Comment voulez-vous les gars approcher cela?

+0

N'est-il pas possible que vous obteniez des lignes dupliquées, si un lien PageItem vers cet ID et un autre PageItem le lient indirectement via Paragraphe? Vous voulez ces doublons? –

+0

Les doublons @TimSchmelter ne posent aucun problème, je peux les filtrer plus tard. –

+0

@GertArnold, toutes les tables ont les clés étrangères appropriées pour que les propriétés de navigation soient exactement là où vous les attendez. Oui L2S pas EF. –

Répondre

1

Mon expérience est que cela fonctionne mieux pour commencer une requête LINQ par les éléments que vous souhaitez revenir à la fin, puis ajoutez les prédicats nécessaires:

var result = context.Lines ... 

Vous voulez des lignes qui appartiennent à un Page spécifique - - Disons que vous avez une variable pageId. Les lignes peuvent appartenir à un Page directement par PageItem s ...

var result = context.Lines 
        .Where(l => l.PageItems.Any(pi => pi.PageId == pageId)) ... 

... ou par ParagraphItem s, Paragraph et PageItem s:

var result = context.Lines 
        .Where(l => l.PageItems.Any(pi => pi.PageId == pageId) 
          || l.ParagraphItems.Any(pa => pa.Paragraph.PageItems 
            .Any(pi1 => pi1.PageId == pageId))); 

Cela se traduira par Exist efficaces et prédicats En raison de la nature de la requête, aucun doublon ne sera renvoyé.

+0

Cette requête est vraiment rapide. Fonctionne très bien pour moi. Merci!! –