2016-04-13 5 views
5

Sto avendo un elenco di raccolta BossList. In questo sto usando nested. Any() per determinare la condizione. Ora la performance è molto lenta nel mio vero progetto. Si consideri il seguente codice sorgente di esempio.Come evitare annidato consecutivamente. Qualunque in C# LINQ

void Main() 
{ 

    List<Boss> BossList = new List<Boss>() 
    { 
     new Boss() 
     { 
      ID = 101, 
      Name = "Harry", 
      Department = "Development", 
      Gender = "Male", 
      Role = "Manager", 
      Employees = new List<Person>() { 
       new Person() { 
        ID = 101, 
        SID = 102, 
        Name = "Peter", 
        Department = "Development", 
        Gender = "Male", 
        Role = "Assistant", 
        PayInfo = new List<PayrollInfo>() 
        { 
         new PayrollInfo() { Monthof2015 = 1, NetWorkingDays = 24, AbsentDays = 6 }, 
         new PayrollInfo() { Monthof2015 = 2, NetWorkingDays = 23, AbsentDays = 3 }, 
         new PayrollInfo() { Monthof2015 = 3, NetWorkingDays = 20, AbsentDays = 2 }, 
         new PayrollInfo() { Monthof2015 = 4, NetWorkingDays = 22, AbsentDays = 1 }, 
         new PayrollInfo() { Monthof2015 = 5, NetWorkingDays = 24, AbsentDays = 4 }, 
         new PayrollInfo() { Monthof2015 = 6, NetWorkingDays = 26, AbsentDays = 6 }, 
         new PayrollInfo() { Monthof2015 = 7, NetWorkingDays = 25, AbsentDays = 4 }, 
         new PayrollInfo() { Monthof2015 = 8, NetWorkingDays = 21, AbsentDays = 3 }, 
         new PayrollInfo() { Monthof2015 = 9, NetWorkingDays = 20, AbsentDays = 8 }, 
         new PayrollInfo() { Monthof2015 = 10, NetWorkingDays = 25, AbsentDays = 9 }, 
         new PayrollInfo() { Monthof2015 = 11, NetWorkingDays = 24, AbsentDays = 4 }, 
         new PayrollInfo() { Monthof2015 = 12, NetWorkingDays = 26, AbsentDays = 1 }, 
        } 
       }, 
       new Person() { 
        ID = 101, 
        SID = 103, 
        Name = "Emma Watson", 
        Department = "Development", 
        Gender = "Female", 
        Role = "Assistant", 
        PayInfo = new List<PayrollInfo>() { 
         new PayrollInfo() { Monthof2015 = 1, NetWorkingDays = 24, AbsentDays = 5 }, 
         new PayrollInfo() { Monthof2015 = 2, NetWorkingDays = 23, AbsentDays = 3 }, 
         new PayrollInfo() { Monthof2015 = 3, NetWorkingDays = 20, AbsentDays = 3 }, 
         new PayrollInfo() { Monthof2015 = 4, NetWorkingDays = 22, AbsentDays = 4 }, 
         new PayrollInfo() { Monthof2015 = 5, NetWorkingDays = 24, AbsentDays = 1 }, 
         new PayrollInfo() { Monthof2015 = 6, NetWorkingDays = 26, AbsentDays = 9 }, 
         new PayrollInfo() { Monthof2015 = 7, NetWorkingDays = 25, AbsentDays = 4 }, 
         new PayrollInfo() { Monthof2015 = 8, NetWorkingDays = 21, AbsentDays = 3 }, 
         new PayrollInfo() { Monthof2015 = 9, NetWorkingDays = 20, AbsentDays = 1 }, 
         new PayrollInfo() { Monthof2015 = 10, NetWorkingDays = 25, AbsentDays = 2 }, 
         new PayrollInfo() { Monthof2015 = 11, NetWorkingDays = 24, AbsentDays = 1 }, 
         new PayrollInfo() { Monthof2015 = 12, NetWorkingDays = 26, AbsentDays = 1 }, 
        } 
       }, 

      } 
     }, 
     new Boss() 
     { 
      ID = 104, 
      Name = "Raj", 
      Department = "Development", 
      Gender = "Male", 
      Role = "Manager", 
      Employees = new List<Person>() 
      { 
       new Person() { 
        ID = 104, 
        SID = 105, 
        Name = "Kaliya", 
        Department = "Development", 
        Gender = "Male", 
        Role = "Assistant", 
        PayInfo = new List<PayrollInfo>() { 
         new PayrollInfo() { Monthof2015 = 1, NetWorkingDays = 24, AbsentDays = 6 }, 
         new PayrollInfo() { Monthof2015 = 2, NetWorkingDays = 23, AbsentDays = 3 }, 
         new PayrollInfo() { Monthof2015 = 3, NetWorkingDays = 20, AbsentDays = 2 }, 
         new PayrollInfo() { Monthof2015 = 4, NetWorkingDays = 22, AbsentDays = 1 }, 
         new PayrollInfo() { Monthof2015 = 5, NetWorkingDays = 24, AbsentDays = 4 }, 
         new PayrollInfo() { Monthof2015 = 6, NetWorkingDays = 26, AbsentDays = 6 }, 
         new PayrollInfo() { Monthof2015 = 7, NetWorkingDays = 25, AbsentDays = 4 }, 
         new PayrollInfo() { Monthof2015 = 8, NetWorkingDays = 21, AbsentDays = 3 }, 
         new PayrollInfo() { Monthof2015 = 9, NetWorkingDays = 20, AbsentDays = 8 }, 
         new PayrollInfo() { Monthof2015 = 10, NetWorkingDays = 25, AbsentDays = 9 }, 
         new PayrollInfo() { Monthof2015 = 11, NetWorkingDays = 24, AbsentDays = 4 }, 
         new PayrollInfo() { Monthof2015 = 12, NetWorkingDays = 26, AbsentDays = 1 }, 
        } 
       }, 
       new Person() { 
        ID = 104, 
        SID = 103, 
        Name = "Emma Watson", 
        Department = "Development", 
        Gender = "Female", 
        Role = "Assistant", 
        PayInfo = new List<PayrollInfo>() { 
         new PayrollInfo() { Monthof2015 = 1, NetWorkingDays = 24, AbsentDays = 5 }, 
         new PayrollInfo() { Monthof2015 = 2, NetWorkingDays = 23, AbsentDays = 3 }, 
         new PayrollInfo() { Monthof2015 = 3, NetWorkingDays = 20, AbsentDays = 3 }, 
         new PayrollInfo() { Monthof2015 = 4, NetWorkingDays = 22, AbsentDays = 4 }, 
         new PayrollInfo() { Monthof2015 = 5, NetWorkingDays = 24, AbsentDays = 1 }, 
         new PayrollInfo() { Monthof2015 = 6, NetWorkingDays = 26, AbsentDays = 9 }, 
         new PayrollInfo() { Monthof2015 = 7, NetWorkingDays = 25, AbsentDays = 4 }, 
         new PayrollInfo() { Monthof2015 = 8, NetWorkingDays = 21, AbsentDays = 3 }, 
         new PayrollInfo() { Monthof2015 = 9, NetWorkingDays = 20, AbsentDays = 1 }, 
         new PayrollInfo() { Monthof2015 = 10, NetWorkingDays = 25, AbsentDays = 2 }, 
         new PayrollInfo() { Monthof2015 = 11, NetWorkingDays = 24, AbsentDays = 1 }, 
         new PayrollInfo() { Monthof2015 = 12, NetWorkingDays = 26, AbsentDays = 1 }, 
        } 
       }, 

      }, 
     }, 
     new Boss() 
     { 
      ID = 102, 
      Name = "Peter", 
      Department = "Development", 
      Gender = "Male", 
      Role = "Manager", 
      Employees = new List<Person>() 
      { 
       new Person() { 
        ID = 102, 
        SID = 105, 
        Name = "Kaliya", 
        Department = "Development", 
        Gender = "Male", 
        Role = "Assistant", 
        PayInfo = new List<PayrollInfo>() { 
         new PayrollInfo() { Monthof2015 = 1, NetWorkingDays = 24, AbsentDays = 6 }, 
         new PayrollInfo() { Monthof2015 = 2, NetWorkingDays = 23, AbsentDays = 3 }, 
         new PayrollInfo() { Monthof2015 = 3, NetWorkingDays = 20, AbsentDays = 2 }, 
         new PayrollInfo() { Monthof2015 = 4, NetWorkingDays = 22, AbsentDays = 1 }, 
         new PayrollInfo() { Monthof2015 = 5, NetWorkingDays = 24, AbsentDays = 4 }, 
         new PayrollInfo() { Monthof2015 = 6, NetWorkingDays = 26, AbsentDays = 6 }, 
         new PayrollInfo() { Monthof2015 = 7, NetWorkingDays = 25, AbsentDays = 4 }, 
         new PayrollInfo() { Monthof2015 = 8, NetWorkingDays = 21, AbsentDays = 3 }, 
         new PayrollInfo() { Monthof2015 = 9, NetWorkingDays = 20, AbsentDays = 8 }, 
         new PayrollInfo() { Monthof2015 = 10, NetWorkingDays = 25, AbsentDays = 9 }, 
         new PayrollInfo() { Monthof2015 = 11, NetWorkingDays = 24, AbsentDays = 4 }, 
         new PayrollInfo() { Monthof2015 = 12, NetWorkingDays = 26, AbsentDays = 1 }, 
        } 
       }, 
       new Person() { 
        ID = 102, 
        SID = 103, 
        Name = "Emma Watson", 
        Department = "Development", 
        Gender = "Female", 
        Role = "Assistant", 
        PayInfo = new List<PayrollInfo>() { 
         new PayrollInfo() { Monthof2015 = 1, NetWorkingDays = 24, AbsentDays = 5 }, 
         new PayrollInfo() { Monthof2015 = 2, NetWorkingDays = 23, AbsentDays = 3 }, 
         new PayrollInfo() { Monthof2015 = 3, NetWorkingDays = 20, AbsentDays = 3 }, 
         new PayrollInfo() { Monthof2015 = 4, NetWorkingDays = 22, AbsentDays = 4 }, 
         new PayrollInfo() { Monthof2015 = 5, NetWorkingDays = 24, AbsentDays = 1 }, 
         new PayrollInfo() { Monthof2015 = 6, NetWorkingDays = 26, AbsentDays = 9 }, 
         new PayrollInfo() { Monthof2015 = 7, NetWorkingDays = 25, AbsentDays = 4 }, 
         new PayrollInfo() { Monthof2015 = 8, NetWorkingDays = 21, AbsentDays = 3 }, 
         new PayrollInfo() { Monthof2015 = 9, NetWorkingDays = 20, AbsentDays = 1 }, 
         new PayrollInfo() { Monthof2015 = 10, NetWorkingDays = 25, AbsentDays = 2 }, 
         new PayrollInfo() { Monthof2015 = 11, NetWorkingDays = 24, AbsentDays = 1 }, 
         new PayrollInfo() { Monthof2015 = 12, NetWorkingDays = 26, AbsentDays = 1 }, 
        } 
       } 
      } 
     } 
    }; 

    BossList.Where(i => i.Employees.Any(j => j.PayInfo.Any(s => s.AbsentDays >6))).Select(m => m.Name).Dump(); 
} 

classi del modello saranno

public class Person 
{ 
    public int ID { get; set; } 
    public int SID { get; set; } 
    public string Name { get; set; } 
    public string Department { get; set; } 
    public string Gender { get; set; } 
    public string Role { get; set; } 
    public List<PayrollInfo> PayInfo { get; set; } 
} 

public class Boss 
{ 
    public int ID { get; set; } 
    public int SID { get; set; } 
    public string Name { get; set; } 
    public string Department { get; set; } 
    public string Gender { get; set; } 
    public string Role { get; set; } 
    public List<Person> Employees { get; set; } 
} 

public class PayrollInfo 
{ 
    public int Monthof2015 { get; set; } 
    public int NetWorkingDays { get; set; } 
    public int AbsentDays { get; set; } 
} 

Il principale LINQ Query è

BossList.Where(i => i.Employees 
         .Any(j => j.PayInfo 
           .Any(s => s.AbsentDays >6))) 
     .Select(m => m.Name); 

nel mio progetto principale, contiene 6 nidificati .Any(). Qui non riesco a creare a causa del lungo codice.

Sto utilizzando la query in EF come IQueryable. Il database contiene più di 1000 record.

Gentilmente suggeritemi, esiste un modo efficace per massimizzare le prestazioni?

+1

Grazie per il codice LINQPad! Questa è una versione semplificata di una query EF? –

+0

@stuartd - Sto usando la query in EF come IQueryable. –

+0

@IvanStoev - L'ho aggiunto alla domanda. –

risposta

1

Probabilmente il modo migliore per farlo è ancora utilizzando BossList come punto di partenza, ma costruire un elenco di ID in cui dovessero verificarsi i loro Ids:

db.BossList.Where(b => db.PayrollInfos.Where(s => s.AbsentDays >6) 
           .Select(p => p.Employee.BossId) 
        .Contains(b.BossId)); 

In SQL questo sarà probabilmente tradursi in un modo accurato ed efficiente EXISTS query.

Nota che presumo che nel modello di vita reale ci siano riferimenti a ritroso (PayrollInfos.Employee) e che io abbia usato un segnaposto BossId che dovresti sostituire con le proprietà chiave reali. Dal tuo esempio non è chiaro come funzionano i riferimenti ID e SID.

db è l'istanza DbContext.

Per spiegare questo approccio un po 'di più: nella mia esperienza di solito funziona meglio per avviare una query con la raccolta che contiene i risultati che stai dopo, cioè Bosslist, e quindi aggiungere predicati che filtrano i risultati. Altre risposte iniziano con PayrollInfo. Va bene, ma alla fine è necessario il raggruppamento o Distinct per rimuovere i duplicati. Di solito questo non rende il piano di query migliore di un semplice table WHERE EXSIST(subqyery).

+0

Potete per favore elaborarlo per favore. –

+0

Sono nuovo in questo LINQ. Si prega di riassumere il codice per favore in particolare PayrollInfos –

+0

Ho aggiunto qualche chiarimento. –

1

Cosa succede se si aggiunge qualcosa come chiave esterna a "genitore" in ogni entità?

public class PayrollInfo 
{ 
    public int Monthof2015 { get; set; } 
    public int NetWorkingDays { get; set; } 
    public int AbsentDays { get; set; } 
    public Person Person { get; set; } 
} 

E quando è possibile impostare la nuova proprietà, mentre la creazione Person - parametro nel costruttore:

public Person(IList<PayrollInfo> list) 
{ 
    this.PayInfo = list; 
    foreach(var pay in this.PayInfo) 
     pay.Person = this; 
} 

O semplicemente definire un metodo che imposta PayInfo. Qualunque cosa ti piaccia E poi fai lo stesso per Persona e Capo. E poi si potrebbe scrivere smth come

AllPayrollInfos.Where(x => x.Days > 6).GroupBy(x => x.Person.Boss).Select(x => x.Key).ToList(); 
1

Supponendo che questa è una query EF annacquato; Vorrei invertire la selezione per iniziare con PayrollInfo e quindi selezionare il nome del Boss:

Boss Boss = new Boss 
{ 
    ID = 101, 
    Name = "Harry", 
    Department = "Development", 
    Gender = "Male", 
    Role = "Manager", 
}; 
Person Person = new Person() { ID = 101, SID = 102, Name = "Peter", Department = "Development", Gender = "Male", Role = "Assistant", Boss = Boss}; 
List<PayrollInfo> PayrollInfoList = new List<UserQuery.PayrollInfo> 
{ 
    new PayrollInfo() { Monthof2015 = 1, NetWorkingDays = 24, AbsentDays = 6, Person = Person }, 
    new PayrollInfo() { Monthof2015 = 2, NetWorkingDays = 23, AbsentDays = 3, Person = Person }, 
    new PayrollInfo() { Monthof2015 = 3, NetWorkingDays = 20, AbsentDays = 2, Person = Person }, 
    new PayrollInfo() { Monthof2015 = 4, NetWorkingDays = 22, AbsentDays = 1, Person = Person }, 
    new PayrollInfo() { Monthof2015 = 5, NetWorkingDays = 24, AbsentDays = 4, Person = Person }, 
    new PayrollInfo() { Monthof2015 = 6, NetWorkingDays = 26, AbsentDays = 6, Person = Person }, 
    new PayrollInfo() { Monthof2015 = 7, NetWorkingDays = 25, AbsentDays = 4, Person = Person }, 
    new PayrollInfo() { Monthof2015 = 8, NetWorkingDays = 21, AbsentDays = 3, Person = Person }, 
    new PayrollInfo() { Monthof2015 = 9, NetWorkingDays = 20, AbsentDays = 8, Person = Person }, 
    new PayrollInfo() { Monthof2015 = 10, NetWorkingDays = 25, AbsentDays = 9, Person = Person }, 
    new PayrollInfo() { Monthof2015 = 11, NetWorkingDays = 24, AbsentDays = 4, Person = Person }, 
    new PayrollInfo() { Monthof2015 = 12, NetWorkingDays = 26, AbsentDays = 1, Person = Person }, 
}; 


PayrollInfoList.Where(p => p.AbsentDays > 6).Select(p => p.Person.Boss.Name).Distinct().Dump();