【问题标题】:EF Code First - Include(x => x.Properties.Entity) a 1 : Many associationEF Code First - Include(x => x.Properties.Entity) a 1 : 许多关联
【发布时间】:2011-07-06 18:54:35
【问题描述】:

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

public class Person { ... }

其中有一个集合:

public class Address { ... }

只有一个关联:

public class Mailbox { ... }

我想做:

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

不使用魔法字符串。我想使用 lambda 表达式。

我知道我在上面输入的内容将被编译,并将带回所有符合搜索条件的人,他们的地址和每个地址的邮箱都急切加载,但它在一个让我恼火的字符串中。

没有字符串怎么办?

感谢堆栈!

【问题讨论】:

    标签: c#-4.0 entity-framework-ctp5 ef-code-first


    【解决方案1】:

    在这篇文章中有描述: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;
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

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

        您可以在herehere 中找到其他示例。

        【讨论】:

        • 很好地使用 Select。从来没有考虑过。 +1
        猜你喜欢
        • 2011-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多