简体   繁体   English

将Linq查询转换为表达式树

[英]Converting Linq query to expression tree

I have a lambda expression: 我有一个lambda表达式:

query = query.Include(e => e.Product);

How do I represent e => e.Product via an Expression tree so that i can make it dynamically at runtime? 如何通过表达式树表示e => e.Product ,以便可以在运行时动态创建它?

You can dynamically create such expression like this: 您可以像这样动态创建这样的表达式:

// Declare input parameter of dynamically generated lambda expression
var parameterExpr = Expression.Parameter(typeof(e), "e");

// Select desired navigation property that should be included in a query result
var propertyExpr = Expression.Property(parameterExpr, "Product");

// Generate expression to cast value of this property to type Object. This is
// not strictly needed (if you know type of included property at compile-time).
var convertExpr = Expression.Convert(propertyExpr, typeof(Object));

// Create lambda expression. Thanks to previous "Expression.Convert",
// we can cast lambda to Expression<Func<e, Object>> instead of 
// Expression<Func<e, Product>> (because since you want to create expression
// dynamically, type of Product property is not necesarilly known at compile-time)
var lambdaExpr = (Expression<Func<e, Object>>)Expression.Lambda(convertExpr, parameterExpr);

// Use generated expression in a query
query = query.Include(lambdaExpr);

BTW: EF Core (and possibly EF6 too, but I don't have experience with it) has overload of the .Include() method that takes property name as an argument, so you actually don't need to generate expression tree at all: 顺便说一句: EF Core (可能还有EF6 ,但我没有经验)具有以属性名作为参数的.Include()方法的重载,因此您实际上根本不需要生成表达式树:

query = query.Include("Product");

As you didn't provide your types I created my own, so your expression will look a little different. 由于您没有提供您的类型,因此我创建了自己的类型,因此您的表情看起来会有些不同。

using System;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;

namespace ConsoleApp2
{
    class Product
    {

    }

    class Shop
    {

    }

    class SomeEntity
    {
        public Product Product { get; set; }
        public Shop Shop { get; set; }
    }

    class MyDbContext : DbContext
    {
        public DbSet<SomeEntity> Entities { get; set; }
    }

    class Program
    {
        private static Expression<Func<SomeEntity, Object>> GetExpression()
        {
            // a stupid random strategy
            if (DateTime.Now.Ticks % 2 == 0)
            {
                Expression<Func<SomeEntity, Object>> expression = e => e.Shop;
                return expression;
            }
            else
            {
                Expression<Func<SomeEntity, Object>> expression = e => e.Product;
                return expression;
            }
        }

        static void Main(string[] args)
        {
            var dbContext = new MyDbContext();

            IQueryable<SomeEntity> query = dbContext.Entities;

            var expression = GetExpression();

            query = query.Include(expression);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM