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

发布于 2024-10-19 19:23:21 字数 489 浏览 3 评论 0原文

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

public class Person { ... }

它具有以下集合:

public class Address { ... }

其具有单个关联:

public class Mailbox { ... }

我想做:

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

不使用魔术字符串。我想使用 lambda 表达式来完成此操作。

我知道我上面输入的内容将进行编译,并将带回所有与搜索条件匹配的人员及其地址以及每个地址的邮箱渴望加载的内容,但它是在一个字符串中,这让我很恼火。

没有绳子怎么办?

谢谢堆栈!

Given a EF-Code First CTP5 entity layout like:

public class Person { ... }

which has a collection of:

public class Address { ... }

which has a single association of:

public class Mailbox { ... }

I want to do:

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

WITHOUT using a magic string. I want to do it using a lambda expression.

I am aware what I typed above will compile and will bring back all Persons matching the search criteria with their addresses and each addresses' mailbox eager loaded, but it's in a string which irritates me.

How do I do it without a string?

Thanks Stack!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

纸短情长 2024-10-26 19:23:21

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

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

您可以在这里此处

For that you can use the Select method:

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

You can find other examples in here and here.

成熟的代价 2024-10-26 19:23:21

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

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

For any one thats still looking for a solution to this, the Lambda includes is part of EF 4+ and it is in the System.Data.Entity namespace; examples here

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

北风几吹夏 2024-10-26 19:23:21

这篇文章中对此进行了描述: 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;
        }
    }
}

It is described in this post: http://www.thomaslevesque.com/2010/10/03/entity-framework-using-include-with-lambda-expressions/

Edit (By Asker for readability):
The part you are looking for is below:

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;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文