2010-12-04 3 views
1

J'ai cette requête pour obtenir des données via Entity Framework, qui fonctionne aujourd'hui. Chose est, je veux créer la requête de manière dynamique, c'est-à-dire la construire en blocs, mais je ne peux pas comprendre exactement comment le faire. Je crois que si je peux en quelque sorte sauvegarder l'une des valeurs que je récupère au début, je peux le faire, mais maintenant je le récupère deux fois (probablement un peu lent aussi, à moins que le compilateur ne le corrige avant de triturer). Logique? Voici le LINQ:Comment puis-je simplifier cette requête LINQ-To-Entity et la rendre dynamique

from d in db.trains 
where d.cancelled 
&& d.station == toStation 
&& d.date >= fromDate.Date 
&& d.date <= toDate.Date 
&& (from k in db.trains 
    where 
    k.date == d.date 
    && k.trainId == d.trainId 
    && k.stationId == fromStation 
    && k.position <= d.position 
    select k.trainId).Contains(d.trainId) 
select new 
{ 
    trainId = d.trainId, 
    date = d.date, 
    arrival = d.arrival, 
    departure = (from k in db.trains 
       where 
       k.date == d.date 
       && k.trainId == d.trainId 
       && k.stationId == fromStation 
       && k.position <= d.position 
       select k.departure).FirstOrDefault() 
} 
); 

Donc, vous voyez, afin d'obtenir le départ, je dois récupérer à nouveau la même chose. Donc, ce que je demande est-ce que je peux enregistrer l'objet dans la première requête, puis le récupérer plus tard? Je ne peux pas faire fonctionner la syntaxe.

La base de données ressemble à ceci:

trainId stationId date  arrival departure position 

1  99  2010-10-11 10:00 10:10  1 
1  98  2010-10-11 11:20 11:30  2 
1  47  2010-10-11 12:30 12:40  3 
2  99  2010-10-10 15:00 15:10  5 

etc

Alors bascially, je dois récupérer deux objets de la db, où le premier a StationID x et l'autre a StationID y et les deux ont la même date et l'ID de train, et ils doivent être dans le bon ordre, en fonction de la position (les trains vont dans les deux sens, mais avec des ID de train différents).

Aussi, je voudrais faire être en mesure de construire cette requête dynamique, comme ceci:

var trains = from d in db.trains 
      select d; 

if (id > 0) 
    trains = trains.Where(p => p.trainId == id); 

if (date != DateTime.MinValue) 
    trains = trains.Where(p => p.date == date); 

var items = (from train in trains).ToList(); 

i.e. basé sur si différentes variables ont des valeurs.

Répondre

1

Vous pouvez utiliser l'instruction let pour stocker les variables locales et les réutiliser plus tard
Quelque chose comme ceci:

from d in db.trains 
where d.cancelled 
&& d.station == toStation 
&& d.date >= fromDate.Date 
&& d.date <= toDate.Date 
let departures = (from k in db.trains 
    where 
    k.date == d.date 
    && k.trainId == d.trainId 
    && k.stationId == fromStation 
    && k.position <= d.position 
    select k) 
where departures.Select(d => d.trainId).Contains(d.trainId) 
select new 
{ 
    trainId = d.trainId, 
    date = d.date, 
    arrival = d.arrival, 
    departure = departures.Select(d => d.departure).FirstOrDefault() 
} 
); 
+0

Aha, je savais qu'il y aurait quelque chose comme ça :) Parfait. Juste un problème, comment puis-je récupérer différentes valeurs de la liste "départs", c'est-à-dire d'abord vérifier s'il contient un objet trainobject avec trainId x, puis récupérer la variable de départ? Je suppose que j'ai besoin de le stocker d'abord comme une liste de trains au lieu de la liste des ID, mais comment puis-je courir contient sur cela? – Johan

+0

@Johan, désolé, lisez rapidement pour voir que c'était différents champs dans les différentes sous-requêtes, j'ai mis à jour ma réponse pour stocker les trains entiers dans la liste des départs. –

+0

Merci Albin, ça a bien marché! J'ai fait quelques tests maintenant et je vois un modèle bizarre. La première requête que je fais comme ceci est généralement plus lente que l'ancienne (surtout avec des résultats plus gros), mais après la première, la nouvelle requête est généralement plus rapide. Savez-vous pourquoi ce serait, le serveur sql cache-t-il mieux la requête ou quelque chose? – Johan

Questions connexes