de manière efficace pour remplir la requête-cadre avec Entify objets connexes?

voix
0

J'utilise EF pour un ensemble d'objets et que vous souhaitez interroger un type d'objet avec les entrées correspondantes de deux autres tables. Ceci est de vider la requête dans une sortie XML. Dans un premier temps , utilisé une jointure depuis dans les données d' origine de chaque employé a toujours 1+ cas d'un ordinateur objet (solution n ° 2 ci - dessous), mais il est pas nécessairement vrai.

Pour des raisons ici, imaginez:

  • un employé objet,
  • chaque employé a un EmployeType (quelques entrées fixes) et
  • chaque employé a zéro ou plusieurs ordinateurs objets (typiquement 0-3).
  • chaque ordinateur appartient à un employé, tous les employés a un ordinateur.
  • chaque employé a un critère sur lequel la recherche est basée (comme division ).

Donc, j'ai vu plusieurs solutions possibles:

  1. Utilisez le Employee.Computer.Load () dans une boucle, mais avec des lignes 10.000+, qui provoque une pénalité énorme performance.

  2. Utilisez une jointure dans la requête, mais qui laisse tous les employés qui ne disposent pas d' un ordinateur .

  3. Utilisez LINQ to Entities, mais qui semble avoir les frais généraux de # 1: lors du chargement d' ordinateur est la base de données , il frappe pour CHAQUE employé .

  4. Utilisez une deuxième requête (tout ordinateur s avec correspondance Computer.Employee.Division ), puis dans l' employé boucle, ajoutez tout ordinateur pour l'employé donné. Alors que la mise en œuvre, je trouve que juste en cours d' exécution de la deuxième requête (avec ToList () ) EF renseigne les bonnes Employee.Computer listes avec les objets dont j'ai besoin.

Ici, les charges # 4 les données avec seulement 2 au lieu de la base de données frappe 10k +, et la EntityFramework en fait les objets les collectent et crée toutes les relations.

Mes questions :

  • Avec # 4, est le fait que l'EF renseigne la Employee.Computer liste quelque chose que je puis - je compter? Si oui, pouvez - vous me montrer à la documentation?
  • Y at-il une meilleure façon que # 4?

Mise à jour : Eh bien, bougre. Désolé, mais je simplement fait sauter. Je me concentrais sur la relation avec la table « informatique » etraté le fait que j'avais explicite Employee.EmployeeTypeReference.Load () w / o premier examen de null, la liste était pas un problème complet « informatique ».

Je ne ai trouvé ce lors de l'exécution des tests de performance et en ajoutant la solution de Craig au mélange. En vérité, les dossiers ne sont pas « employés » et « Ordinateurs », mais des abstractions, et je (sous condition) comprennent tous les champs dans la sortie XML, mais ils sont petits: un nom, ID (PK) et ID (FK) plus INT sur la table « employé ». Donc, ma présomption est que la performance serait similaire puisque l'EF serait de créer des objets pas beaucoup plus lourd que la projection.

Quoi qu'il en soit, voici les résultats wher le temps « écoulé » était la différence avant cette requête et après le XML résultant a été créé.

  • Cas 1: Identique à # 2, mais avec include () déclarations:

    list = ve.Employee.Include(Computer).Include(EmployeeType).Where(e => e.Division.ID == divId).OrderBy(e => e.Name);

    Elapsed: 4,96, 5,05

  • Cas n ° 2: Utilise en ligne Load () :

    list = ve.Employee.Where(e => e.Division.ID == divId).OrderBy(e => e.Name);

    Elapsed: 74,62

  • Cas n ° 3: Identique à # 4, mais avec include () déclarations:

    list = from e in ve.Employee.Include(Computer).Include(EmployeeType) where e.Division.ID == divId orderby e.Name select e;

    Elapsed: 4,91, 5,47

  • Cas n ° 4: Utilise en ligne Load () :

    list = from e in ve.Employee where e.Division.ID == divId orderby e.Name select e;

    Elapsed: 74,20

  • Cas n ° 5: Utiliser * Inclure ( « EmployeType ») et requête « Computer » séparée, laissez associé EF:

    elist = ve.Employee.Include(EmployeeType).Where(te => te.Division.ID == divId).OrderBy(e => e.Name).ToList(); alist = ve.Alias.Where(a => a.Employee.Division.ID == divId).ToList();

    Elapsed: 4,50, 4,02

  • Cas n ° 6: La suggestion de Craig de projections:

    elist = from te in ve.ThesaurusEntry where te.Division.ID==divID orderby te.Name select new { ID = te.ID, Name = te.Name, Type = te.EmployeeType.Name, Freq = te.Frequency, Aliases = from a in te.Alias select new { ID = a.ID, Name = a.Name } };

    Elapsed: 0,73, 1,25

conclusions

Load () est cher, donc l' utilisation Include () ou au moins test avec IsLoaded

La projection est un peu fastidieux, mais nettement plus rapide que EF fix-up. [avec ce test limité sur les tables « étroites »]

Créé 26/08/2009 à 23:16
source utilisateur
Dans d'autres langues...                            


2 réponses

voix
2

Je crois que vous pouvez indiquer que les relations peuvent être préchargés

Dim employees = From emp in db.Employees.Include("Computer") _
                Select emp
Créé 27/08/2009 à 01:06
source utilisateur

voix
1

La solution de Rob fonctionnera (+1), mais si vous n'avez pas besoin tous les champs, par exemple, des employés et de l' ordinateur, je voudrais fortement recommander la projection à la place:

var q = from e in Context.Employees
        where e.Division.Id = divisionId
        select new
        {
            Name = e.Name,
            EmployeeType = e.EmployeeType.Description,
            ComputerIds = from c in e.Computers
                          select new 
                          {
                              Id = c.Id
                          }
        };

Ici , vous obtenez tout ce que vous avez besoin dans une requête, mais rien de plus : Tous les champs que vous ne avez pas besoin ne seront pas retournés.

Vous pouvez probablement choisir même dans XElements et juste sauver l'arbre résultant plutôt que de convertir manuellement en XML. Je ne l' ai pas essayé, mais il semble que cela devrait fonctionner.

En ce qui concerne # 4, oui, vous pouvez compter sur, mais il est toujours bon de vérifier IsLoadedavant d' appeler Load().

Créé 27/08/2009 à 14:17
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more