EF Code First - Include(x => x.Properties.Entity)a 1:许多关联

Vul*_*ary 39 ef-code-first c#-4.0 entity-framework-ctp5

给定EF-Code First CTP5实体布局,如:

public class Person { ... }
Run Code Online (Sandbox Code Playgroud)

它有一个集合:

public class Address { ... }

它有一个单一的关联:

public class Mailbox { ... }

我想要做:

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

没有使用魔法字符串.我想用lambda表达式来做.

我知道我上面输入的内容将编译并将所有匹配搜索条件的人员带回他们的地址和每个地址的邮箱急切加载,但它是一个令我恼火的字符串.

如果没有字符串我该怎么办?

谢谢堆栈!

Mor*_*avi 77

为此,您可以使用Select方法:

PersonQuery.Include(x => x.Addresses.Select(a => a.Mailbox));
Run Code Online (Sandbox Code Playgroud)

您可以在此处此处找到其他示例.

  • 很好用的选择.从来没有考虑过.+1 (6认同)

Ric*_*y G 18

对于仍在寻找解决方案的任何人来说,Lambda包含是EF 4+的一部分,它位于System.Data.Entity命名空间中; 这里的例子

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


vis*_*ssi 7

在这篇文章中描述: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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)