.SelectMany()并从多个相关表中获取数据

Den*_*ail 5 linq entity-framework entity-framework-4

此查询返回员工ID,姓名,公司ID,公司名称和公司城市.我缺少员工电子邮件地址(存储在EmployeeEmailAddress表中的emailAddress)和员工电话号码(存储在EmployeePhoneNumbers表中的phoneNumber).

我需要添加.SelectMany()来获取母公司关系并访问公司ID,名称和城市.但是,现在我无法访问PersonOrgMap表中找不到的任何属性.我无法导航到任何其他表.删除.SelectMany()允许我导航到其他表但我无法访问父公司信息.

var employees = Contacts.Where(c => c.ContactAttributes
.Any (ca => ca.AttributeID == 1153))
.SelectMany (x => x.ChildPersonOrgMaps)
.Select (c => new { employeeId = c.Child.ContactID,
          c.Child.FirstName,
          c.Child.LastName,
          companyId = c.ParentContactID,
          c.Parent.OrganizationName,
          c.Parent.City
        }
         )
.OrderBy (c =>c.LastName ).ThenBy(x => x.FirstName)
.Dump();
Run Code Online (Sandbox Code Playgroud)

Mer*_*nzo 16

如果你热衷于方法语法,那么SelectMany()上的重载也可以让你访问"source"和"result"对象:

.SelectMany(x => x.ChildPersonOrgMaps, (x, c) => new { x, c })
.Select(xc => new 
{ 
    xc.x.Attribute1,
    xc.x.Attribute2,
    xc.c.Child.Attribute3,
    xc.c.Attribute4
});
Run Code Online (Sandbox Code Playgroud)


Joe*_*ari 5

这是查询表达式真正有用的地方.如果你这样开始查询:

from c in Contacts
where c.ContactAttributes.Any (ca => ca.AttributeID == 1153))
from om in c.ChildPersonOrgMaps
...
Run Code Online (Sandbox Code Playgroud)

您将在稍后的查询中访问com变量.C#通过选择"携带"原始变量的临时匿名类型将其转换为SelectMany调用.查看此问题的最佳方法是在LINQPad中将查询编写为查询表达式,然后查看lambda选项卡以查看转换为流畅语法.

  • 无耻的LINQPad插头+1 ;-)非常好的产品! (4认同)