Linq: Вложенные запросы лучше, чем объединения, но что если вы используете 2 вложенных запроса? - PullRequest
2 голосов
/ 10 декабря 2010

В своей книге Entity Framework Джули Лерман рекомендует использовать вложенные запросы в предпочтении по сравнению с объединениями (прокрутите пару страниц). В ее примере см заполняет 1 поле таким образом, но какой идентификатор вы хотите заполнить 2?

У меня есть пример, в котором я бы предпочел заполнить имя и фамилию одним и тем же вложенным запросом, а не двумя отдельными. Мне просто нужно знать правильный синтаксис, чтобы сделать это.

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();
    }
}

Ответы [ 2 ]

3 голосов
/ 10 декабря 2010

В вашем запросе нет ничего плохого, но вы можете написать его гораздо проще, без вложенных запросов:

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();
    }
}

Посмотрите, как я только что удалил ваш from e in db.Employees where ... select e.Forename) и просто заменил егос x.Employee.Forename.Когда ваша база данных содержит правильные отношения внешнего ключа, конструктор EF успешно сгенерирует модель, содержащую свойство Employee для объекта AnnualLeaveBooked.Подобный запрос делает его более читабельным.

Надеюсь, это поможет.

1 голос
/ 10 декабря 2010

попробуйте

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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...