c# 4.0 - Primer código de EF: incluir(x=> x.Properties.Entity) a 1: muchas asociaciones
c#-4.0 entity-framework-ctp5 (3)
Dado un diseño de entidad EF-Code First CTP5 como:
public class Person { ... }
que tiene una colección de:
public class Address { ... }
que tiene una sola asociación de:
public class Mailbox { ... }
Quiero hacer:
PersonQuery.Include(x => x.Addresses).Include("Addresses.Mailbox")
SIN usar una cadena mágica. Quiero hacerlo usando una expresión lambda.
Soy consciente de que lo que escribí arriba compilará y traerá de vuelta a todas las Personas que coincidan con los criterios de búsqueda con sus direcciones y el buzón de cada dirección cargado de impaciencia, pero está en una cadena que me irrita.
¿Cómo lo hago sin una cadena?
Gracias Stack!
Para cualquiera que todavía esté buscando una solución a esto, el Lambda incluye es parte de EF 4+ y está en el espacio de nombres System.Data.Entity; ejemplos aquí
http://romiller.com/2010/07/14/ef-ctp4-tips-tricks-include-with-lambda/
Se describe en esta publicación: http://www.thomaslevesque.com/2010/10/03/entity-framework-using-include-with-lambda-expressions/
Editar (por Asker para facilitar la lectura): la parte que estás buscando está a continuación:
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;
}
}
}