web-dev-qa-db-fra.com

Code EF d'abord - Inclure (x => x.Properties.Entity) une association 1: plusieurs

Étant donné une disposition d'entité CTP5 EF-Code First comme:

public class Person { ... }

qui a une collection de:

public class Address { ... }

qui a une seule association de:

public class Mailbox { ... }

Je veux faire:

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

SANS utiliser de chaîne magique. Je veux le faire en utilisant une expression lambda.

Je sais que ce que j'ai tapé ci-dessus va compiler et ramènera toutes les personnes correspondant aux critères de recherche avec leurs adresses et la boîte aux lettres de chaque adresse chargée, mais c'est dans une chaîne qui m'irrite.

Comment faire sans chaîne?

Merci Stack!

39
VulgarBinary

Pour cela, vous pouvez utiliser la méthode Select:

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

Vous pouvez trouver d'autres exemples dans ici et ici .

77
Morteza Manavi

Pour tous ceux qui recherchent toujours une solution à cela, le Lambda inclut fait partie d'EF 4+ et se trouve dans l'espace de noms System.Data.Entity; exemples ici

http://romiller.com/2010/07/14/ef-ctp4-tips-tricks-include-with-lambda/

18
Ricky G

Il est décrit dans cet article: http://www.thomaslevesque.com/2010/10/03/entity-framework-using-include-with-lambda-expressions/

Edit (Par Asker pour la lisibilité): La partie que vous recherchez est ci-dessous:

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;
        }
    }
}
7
vissi