2017-10-03 4 views
1

Disons que j'ai 4 tableaux A, B, C et D enter image description hereles performances des requêtes simples

Quelle est la meilleure façon d'obtenir la liste des B d'être dans une liste déroulante. La condition est que chaque enregistrement doit avoir associé liste des D1 de sorte que si B n'a pas d'enregistrements D1 je ne devrais pas l'afficher dans la liste déroulante

D1 est une classe enfant de D

Comment je l'ai fait il:

// number 2 to specify the selected A Table normally it's a variable 
var b_Per_A = Uow.B.GetAll().Where(x => x.A_Id == 2).ToList(); 
var b_list = new List<B>(); 
foreach (var b in b_list) 
{ 
    var d = 
     Uow.D1.GetAll().Where(x => x.C.B_Id == b.Id); 
    if (!d.IsNullOrEmpty()) // extension method that checks if a collection is null or empty 
    { 
     b_list.Add(b); 
    } 
} 

il fonctionne, mais il est lent

MISE À JOUR:

La signature de GetAll() est

IQueryable<T> GetAll(); 

MISE À JOUR 2:.

Mon modèle est

public class A 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public IEnumerable<B> ChildBs { get; set; } 
} 
public class B 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public A ParentA { get; set; } 
    public IEnumerable<C> ChildCs { get; set; } 
} 
public class C 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public B ParentB { get; set; } 
    public IEnumerable<D> ChildDs { get; set; } 
} 

public class D 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public C ParentC { get; set; } 
} 

public class D1 : D 
{ 
    /// other properties 
} 
+0

Pourquoi procédure que vous utilisez ne sont pas stockées plutôt que LINQ? –

+0

Avez-vous des propriétés de navigation sur vos objets d'entité? C'est à dire. 'C.ChildDs' et' D.ParentC' –

+0

N'utilisez pas 'GetAll()', puis filtrez-le. Filtrez-le directement sinon, si vous avez 1000 enregistrements, il recevra tous les 1000 enregistrements, puis vous essayez de filtrer ce qui aura un impact sur les performances. – Thennarasan

Répondre

1

Étant donné que vous avez confirmé que vous avez des propriétés de navigation sur vos classes d'entités, cela pourrait être réalisé en une seule expression:

var result = Uow.B.GetAll() 
    .Where(b => 
     b.ParentA.Id == 2 && 
     b.ChildCs.Any() && 
     b.ChildCs.SelectMany(c => c.ChildDs).Any()) 
    .ToList(); 

Cela va pousser le filtrage à votre base de données plutôt que de le faire en mémoire et devrait être beaucoup plus efficace.

En outre, je suppose qu'une propriété de navigation parent ne sera jamais null et que les collections enfant sont toujours initialisées.

Example here

+0

Merci pour votre réponse, je vais essayer, juste le terme de Parent/enfant est confus car il n'y a pas d'héritage. – Maro

+0

@Maro Si vous ajoutez les définitions de modèle d'entité à votre question, je mettrai à jour la réponse pour qu'elle corresponde à vos noms de propriété. –

+0

Votre code fonctionne bien et j'ai obtenu tous les résultats, cependant j'ai fait une erreur oublié de mentionner que la classe D est une sorte de classe abstraite et je cherche l'un de ses enfants, disons D1. Si vous avez une solution, ce serait génial sinon je vais sauf votre réponse car c'était mon erreur de l'oublier. Je vais mettre à jour ma question – Maro

-3

mettre votre var d = Uow.D.GetAll() Où (x => xCB_Id == b.Id); en dehors de votre foreach. Je vous recommande également d'utiliser IEnumerable/ICollection au lieu de List et d'utiliser pour loop au lieu de foreach. La boucle indexée est plus rapide.

+0

donc si vous le mettez hors de la boucle, comment va-t-il l'utiliser pour vérifier avec 'b.id'? plus d'explications nécessaires – Se0ng11