2010-12-10 24 views
2

Dans son livre Entity Framework Julie Lerman, il est recommandé d'utiliser des requêtes imbriquées de préférence aux jointures (faites défiler quelques pages). Dans son exemple, vous pouvez remplir 1 champ de cette façon, mais quel identifiant voulez-vous remplir 2?Linq: Les requêtes imbriquées sont meilleures que les jointures, mais que se passe-t-il si vous utilisez 2 requêtes imbriquées?

J'ai un exemple ici où je préférerais remplir le nom et le prénom avec la même requête imbriquée plutôt que deux séparés. J'ai juste besoin de connaître la syntaxe correcte pour le faire.

public static List<RequestInfo> GetRequests(int _employeeId) 
{ 
    using (SHPContainerEntities db = new SHPContainerEntities()) 
    { 
     return db.AnnualLeaveBookeds 
      .Where(x => x.NextApproverId == _employeeId || 
      (x.ApproverId == _employeeId && x.ApprovalDate.HasValue == false)) 
      .Select(y => new RequestInfo 
      { 
       AnnualLeaveDate = y.AnnualLeaveDate, 
       Forename = (
        from e in db.Employees 
        where e.EmployeeId == y.EmployeeId 
        select e.Forename).FirstOrDefault(), 
       Surname = (
        from e in db.Employees 
        where e.EmployeeId == y.EmployeeId 
        select e.Surname).FirstOrDefault(), 
       RequestDate = y.RequestDate, 
       CancelRequestDate = y.CancelRequestDate, 
       ApproveFlag = false, 
       RejectFlag = false, 
       Reason = string.Empty 
      }) 
      .OrderBy(x => x.AnnualLeaveDate) 
      .ToList(); 
    } 
} 

Répondre

3

Il n'y a rien de mal à votre requête, mais vous pouvez l'écrire d'une manière qui est beaucoup plus simple, sans les requêtes imbriquées:

public static List<RequestInfo> GetRequests(int employeeId) 
{ 
    using (SHPContainerEntities db = new SHPContainerEntities()) 
    { 
     return (
      from x in db.AnnualLeaveBookeds 
      where x.NextApproverId == employeeId || 
       (x.ApproverId == employeeId && x.ApprovalDate == null) 
      orderby x.AnnualLeaveDate 
      select new RequestInfo 
      { 
       AnnualLeaveDate = x.AnnualLeaveDate, 
       Forename = x.Employee.Forename, 
       Surname = x.Employee.Surname, 
       RequestDate = x.RequestDate, 
       CancelRequestDate = x.CancelRequestDate, 
       ApproveFlag = false, 
       RejectFlag = false, 
       Reason = string.Empty 
      }).ToList(); 
    } 
} 

Voyez comment je viens enlevé votre from e in db.Employees where ... select e.Forename) et simplement l'a remplacé avec x.Employee.Forename. Lorsque votre base de données contient les relations de clé étrangère correctes, le concepteur EF générera avec succès un modèle qui contient une propriété Employee sur l'entité AnnualLeaveBooked. Ecrire la requête comme ceci la rend beaucoup plus lisible.

J'espère que cela aide.

+0

Cela a fonctionné, je vous remercie beaucoup. – arame3333

1

essayer cette

using (SHPContainerEntities db = new SHPContainerEntities()) 
{ 
    return db.AnnualLeaveBookeds 
     .Where(x => x.NextApproverId == _employeeId || 
     (x.ApproverId == _employeeId && x.ApprovalDate.HasValue == false)) 
     .Select(y => 
      { 
       var emp = db.Emplyees.Where(e => e.EmployeeId == y.EmployeeId); 
       return new RequestInfo 
        { 
         AnnualLeaveDate = y.AnnualLeaveDate, 
         Forename = emp.Forename, 
         Surname = emp.Surname, 
         RequestDate = y.RequestDate, 
         CancelRequestDate = y.CancelRequestDate, 
         ApproveFlag = false, 
         RejectFlag = false, 
         Reason = string.Empty 
        }; 
      ).OrderBy(x => x.AnnualLeaveDate).ToList(); 
}