2010-08-06 4 views
0

J'ai parcouru ce code dans l'une de nos applications Entity Framework. Je sais qu'il doit y avoir une meilleure façon (plus efficace) que les trois requêtes que ce code exécute. Bien que, je ne peux pas tout à fait obtenir la syntaxe correcte. (J'entends toujours Entity Framework moi-même ..)Entity Framework query

Deux tables sont concernées. C'est une relation parent/enfant simple.

Il existe une table d'appels contenant des informations sur tous nos appels et une table Unités qui contient les numéros de série individuels (unités) attribués à chaque appel. Notez, ce n'est pas une relation de NOMBREUX. La table Unités peut/contiendra des enregistrements en double (numéros de série) !!

Un appel peut contenir 0 à plusieurs enregistrements enfants dans la table Unités. Ainsi, quand un appelant appelle, notre représentant de la sécurité entre un numéro de série (crée toujours un nouvel enregistrement dans la table des unités), qui l'associe à cet appel. À ce stade, nous remplissons un onglet "Historique des appels". Cet onglet est construit par la requête ci-dessous. (Recherche dans la table Unités et recherche toutes les unités correspondant à cette unité, puis renvoie tous les appels affectés à toutes ces unités (enregistrements).)

Pour résumer. L'objectif de la requête est: basé sur le callID, trouver tous les autres appels dans la base de données qui sont également liés à tous les numéros de série affectés à cet appel. Considérant que Entity Framework a créé une Navigation dans la table tblCall appelée "Categories" et dans la table tblCategory appelée "Call", il doit y avoir un moyen meilleur/plus efficace d'écrire cette requête. J'aimerais vraiment le refactoriser. :)

Voici la requête existante:

//First, get all the Serial Numbers assigned to this Call. 
    var serials = from units in context.tblUnits 
       where units.callID == callID 
       select units.unitSerialNumber; 

    List<string> serialsList = serials.ToList<string>(); 

    //Get all of the Call IDs that are assigned to any of the serial numbers from the list above 
    var callIDs = from units in context.tblUnits 
        where serialsList.Contains(units.unitSerialNumber) 
        select units.callID; 

    List<int> callIDList = callIDs.ToList<int>(); 

    //Return all of the calls that are in the callID list from above 
    var data = from calls in context.tblCalls 
       where callIDList.Contains(calls.callID) 
       select calls; 

    result = data.ToList<tblCall>(); 

Tout conseil est beaucoup apprecaited!

Merci pour votre aide Daniel. Voici la dernière question:

var query = (from u1 in context.tblUnits 
      join u2 in context.tblUnits on u1.unitSerialNumber equals u2.unitSerialNumber 
      join c in context.tblCalls on u2.callID equals c.callID 
      where u1.callID == callID 
      select c).Distinct(); 

result = query.ToList(); 

Répondre

0

Je pense que vous pouvez le remplacer par une requête semblable à ceci:

var query = from u1 in context.tblUnits 
     join u2 in context.tblUnits on u1.unitSerialNumber equals u2.unitSerialNumber 
     join c in context.tblCalls on (u2.callID ?? -1) equals c.callID 
     where u1.callID == callID 
     select c; 

var result = query.ToList(); 
+0

Je vais essayer. Merci. Je pensais qu'il pourrait aussi y avoir un moyen de tirer parti des propriétés de navigation sur chaque table aussi. (Par exemple tblCalls a une propriété de navigation "Units" et tblUnits possède une propriété de navigation "Call" ...) – Shayne

+0

Dans ce cas, vous pourriez probablement éliminer la deuxième jointure (à tblCalls) et 'select u2.Call'. –

+0

Alors, vous pensez que cela va fonctionner? var query = de u1 dans context.tblUnits rejoindre u2 context.tblUnits sur u1.unitSerialNumber est égal à u2.unitSerialNumber où u1.callID == 1 select u2.Call; var résultat = query.ToList(); Quel est l'objectif de "u1.callID == 1"? – Shayne