2011-03-01 28 views
37

Dada una disposición entidad EF-Code Primera CTP5 como:Código EF Primera - calcular (x => x.Properties.Entity) 1: Muchos asociación

public class Person { ... } 

que tiene una colección de:

public class Address { ... }

que tiene una sola asociación de:

public class Mailbox { ... }

que quiero hacer:

PersonQuery.Include(x => x.Addresses).Include("Addresses.Mailbox")

sin usar una cadena mágica. Quiero hacerlo usando una expresión lambda.

Entiendo que lo que escribí arriba compilará y traerá de regreso a todas las personas que coincidan con los criterios de búsqueda con sus direcciones y el buzón de cada dirección cargado, pero está en una cadena que me irrita.

¿Cómo lo hago sin una cadena?

Thanks Stack!

Respuesta

75

Para ello se puede utilizar el Seleccione método:

PersonQuery.Include(x => x.Addresses.Select(a => a.Mailbox)); 

Usted puede f y otros ejemplos en here y here.

+6

Niza uso de Select. Nunca considerado eso. +1 – Stimul8d

+0

Eso es exactamente lo que esperaba, ¡gracias! – lehn0058

+0

¡Impresionante! Buen consejo. –

7

Se describe en este post: http://www.thomaslevesque.com/2010/10/03/entity-framework-using-include-with-lambda-expressions/

Editar (autor de la pregunta para facilitar la lectura): La parte que busca es 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; 
     } 
    } 
} 
Cuestiones relacionadas