簡體   English   中英

使用LINQ to Entities的外連接查詢

[英]Outer join query using LINQ to Entities

我公司有0到n個部門,1個部門有0到n個辦公室,1個辦公室有0到n個工作人員。現在我需要使用linq查詢按部門列出員工的平均年齡,如果部門中沒有人則默認平均是0.代碼如下:

    DataContext ctx = new DataContext();

    var q0 = from d in ctx.Departments
             join o in ctx.Offices on d.Id equals o.DepartmentId
             join e in ctx.Employees on o.Id equals e.OfficeId
             group e by d into de
             select new {
                DepartmentId = de.Key.Id,
                AverageAge = de.Count() == 0 ? 0 : de.Average(e => e.Age),
             };


    var q1 = from d in ctx.Departments
             join de in q0 on d.Id equals de.DepartmentId into des
             from de in des.DefaultIfEmpty()
             select new
             {
                 DepartmentName = d.Name,
                 AverageAge = de == null ? 0 : de.AverageAge
             };

    var result = q1.ToList();
    foreach (var item in result)
    {
        Console.WriteLine("{0}-{1}", item.DepartmentName, item.AverageAge);
    }
    ctx.Dispose();

但是如何將q0和q1組合成一個查詢呢?

    were you meaning something along the lines of:

var newQ2 = from d in ctx.Departments
                 outer left join o in ctx.Offices on d.Id equals o.DepartmentId
                 outer left join e in ctx.Employees on o.Id equals e.OfficeId
                 group e by d into de
                 select new {
                    DepartmentId = de.Key.Id,
                    AverageAge = de.Count() == 0 ? 0 : de.Average(e => e.Age),
                 };

變成:

var newQ2 = from d in ctx.Departments
                     join o in ctx.Offices on d.Id equals o.DepartmentId
                     join e in ctx.Employees on o.Id equals e.OfficeId
                     group e by d into de.DefaultIfEmpty()
                     select new {
                        DepartmentId = de.Key.Id,
                        DepartdentName = select d.Name from d where d.id = de.Key.Id,
                        AverageAge = de.Count() == 0 ? 0 : de.Average(e => e.Age),
                     };

附錄:我會使用一個子選項來匹配額外的名稱,不知道我從你的代碼中即興創建的數據庫布局,但你可以使它更高效,並且還有基於子選擇的多部分連接。 對不起,我不能在工作中測試這個代碼,我可以很好地估計,但如果你需要更詳細的答案,需要更多關於你的部門名稱所在位置的信息:)我已經將左外連接更改回連接,抱歉我忘記在c#中使用linq你可以使用DefaultIfEmpty()在代碼中引起外部左連接行為。

外部左連接將返回沒有相應值的空值,但允許返回具有相應值的任何部分。 然而,加入不會返回任何空條目,我懷疑這是為什么你有兩個查詢?

我提出的查詢的唯一警告是,如果它們是空值,您將需要在使用之前填充所需的任何值,例如,如果DE為null,則DepartmentId將需要一些邏輯來填充它。

謝謝大家,我得到了答案:

        var q1 = 
                 from d in ctx.Departments 
                 from o in ctx.Offices.Where(o => o.DepartmentId == d.Id).DefaultIfEmpty()
                 from e in ctx.Employees.Where(e =>  e.OfficeId == o.Id).DefaultIfEmpty()
                 group e by d into de
                 select new {
                    DepartmentName = de.Key.Name,
                    AverageAge = de.Average(e => e == null ? 0 : e.Age),
                 };

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM