Последний подход выглядит довольно ужасно для меня.Я полагаю, что каждый раз нужно будет по-настоящему создавать нового делегата, так как вы каждый раз захватываете другого клиента, но лично я бы не стал делать это вообще.Учитывая, что у вас есть реальные утверждения, почему бы не написать нормальный метод?
private static ToExpando(XElement client)
{
// Possibly use an object initializer instead?
dynamic o = new ExpandoObject();
o.OnlineDetails = new ExpandoObject();
o.OnlineDetails.Password = client.Element(XKey.onlineDetails)
.Element(XKey.password).Value;
o.OnlineDetails.Roles = client.Element(XKey.onlineDetails)
.Element(XKey.roles)
.Elements(XKey.roleId)
.Select(xroleid => xroleid.Value);
return o;
}
, а затем запросить его с помощью:
var qClients = xdoc.Root.Element(XKey.clients)
.Elements(XKey.client)
.Select(ToExpando);
Я был бы много больше заботятся о читабельности кода, чем о производительности создания делегатов, что обычно довольно быстро.Я не думаю, что есть необходимость использовать почти столько же лямбд, сколько вам сейчас хочется.Подумайте, когда вы вернетесь к этому коду через год.Вы действительно собираетесь найти вложенную лямбду проще для понимания, чем метод?
(Кстати, разделение логики преобразования на метод упрощает тестирование в отдельности ...)
РЕДАКТИРОВАТЬ: Даже если вы do хотите сделать все это в выражении LINQ, почему вы так стремитесь создать еще один уровень косвенности?Только потому, что выражения запроса не допускают лямбда-выражения?Учитывая, что вы делаете только простой выбор, с этим легко справиться:
var qClients = xdoc.Root
.Element(XKey.clients)
.Elements(XKey.client)
.Select(client => {
dynamic o = new ExpandoObject();
o.OnlineDetails = new ExpandoObject();
o.OnlineDetails.Password = client.Element(XKey.onlineDetails)
.Element(XKey.password).Value;
o.OnlineDetails.Roles = client.Element(XKey.onlineDetails)
.Element(XKey.roles)
.Elements(XKey.roleId)
.Select(xroleid => xroleid.Value);
return o;
});