此查询返回员工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();
答案 0 :(得分: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
});
答案 1 :(得分:5)
这是查询表达式真正有用的地方。如果你这样开始查询:
from c in Contacts
where c.ContactAttributes.Any (ca => ca.AttributeID == 1153))
from om in c.ChildPersonOrgMaps
...
您稍后可以在查询中访问 c 和 om 变量。 C#通过选择“携带”原始变量的临时匿名类型将其转换为SelectMany调用。查看此问题的最佳方法是在LINQPad中将查询编写为查询表达式,然后查看lambda选项卡以查看转换为流利语法。
答案 2 :(得分:0)
我同意Joe Albahari - 使用查询语法。这是(我所知道的)你可以使用方法语法无法进行查询的一件事。
您可以尝试选择包含父对象和子对象的匿名类型,但我不认为EF会非常喜欢它。
var employees = Contacts.Where(c => c.ContactAttributes
.Any (ca => ca.AttributeID == 1153))
.SelectMany (x => new { Parent = x, Child = x.ChildPersonOrgMaps })
// etc
答案 3 :(得分:0)
我正在学习LINQ,我更喜欢拆分命令,这样我就可以知道发生了什么。作为接受的答案,它肯定没有效率,但可能会被正在学习LINQ的任何人使用。
我宁愿用一些虚拟数据进行演示
var persons = new [] {"John's", "Mike's", "Albert's"};
var objects = new [] {"car", "house", "bicycle"};
var colors = new [] {"red", "blue", "green", "yellow"};
var firstPair = persons.SelectMany(_ => objects, (p, o) => new {
Person = p,
Object = o
});
var secondPair = firstPair.SelectMany(_ => colors, (fp, c) => new {
Person = fp.Person,
Object = fp.Object,
Color = c
});
它在LINQ Pad中提供这样的输出。 enter image description here