Ответ 1
Для этого вы можете использовать метод Select:
PersonQuery.Include(x => x.Addresses.Select(a => a.Mailbox));
Учитывая EF-код Первый CTP5-объект, например:
public class Person { ... }
который имеет набор:
public class Address { ... }
который имеет единственную ассоциацию:
public class Mailbox { ... }
Я хочу сделать:
PersonQuery.Include(x => x.Addresses).Include("Addresses.Mailbox")
БЕЗ использования магической строки. Я хочу сделать это, используя выражение лямбда.
Я знаю, что я набрал выше, скомпилирует и вернет всех лиц, соответствующих критериям поиска, с их адресами и загруженным почтовым ящиком каждого адреса, но это в строке, которая раздражает меня.
Как мне это сделать без строки?
Спасибо Stack!
Для этого вы можете использовать метод Select:
PersonQuery.Include(x => x.Addresses.Select(a => a.Mailbox));
Для любого, кто все еще ищет решение для этого, Lambda включает часть EF 4+ и находится в пространстве имен System.Data.Entity; примеры здесь
http://romiller.com/2010/07/14/ef-ctp4-tips-tricks-include-with-lambda/
В этом сообщении описано: http://www.thomaslevesque.com/2010/10/03/entity-framework-using-include-with-lambda-expressions/
Изменить (по Asker для удобочитаемости): Часть, которую вы ищете, находится ниже:
public static class ObjectQueryExtensions
{
public static ObjectQuery<T> Include<T>(this ObjectQuery<T> query, Expression<Func<T, object>> selector)
{
string path = new PropertyPathVisitor().GetPropertyPath(selector);
return query.Include(path);
}
class PropertyPathVisitor : ExpressionVisitor
{
private Stack<string> _stack;
public string GetPropertyPath(Expression expression)
{
_stack = new Stack<string>();
Visit(expression);
return _stack
.Aggregate(
new StringBuilder(),
(sb, name) =>
(sb.Length > 0 ? sb.Append(".") : sb).Append(name))
.ToString();
}
protected override Expression VisitMember(MemberExpression expression)
{
if (_stack != null)
_stack.Push(expression.Member.Name);
return base.VisitMember(expression);
}
protected override Expression VisitMethodCall(MethodCallExpression expression)
{
if (IsLinqOperator(expression.Method))
{
for (int i = 1; i < expression.Arguments.Count; i++)
{
Visit(expression.Arguments[i]);
}
Visit(expression.Arguments[0]);
return expression;
}
return base.VisitMethodCall(expression);
}
private static bool IsLinqOperator(MethodInfo method)
{
if (method.DeclaringType != typeof(Queryable) && method.DeclaringType != typeof(Enumerable))
return false;
return Attribute.GetCustomAttribute(method, typeof(ExtensionAttribute)) != null;
}
}
}