Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将Linq查询转换为表达式树_C#_Linq_.net Core - Fatal编程技术网

C# 将Linq查询转换为表达式树

C# 将Linq查询转换为表达式树,c#,linq,.net-core,C#,Linq,.net Core,我有一个lambda表达式: query = query.Include(e => e.Product); 如何通过表达式树表示e=>e.Product,以便在运行时动态生成它?您可以动态创建这样的表达式: // Declare input parameter of dynamically generated lambda expression var parameterExpr = Expression.Parameter(typeof(e), "e"); // Select des

我有一个lambda表达式:

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

如何通过表达式树表示e=>e.Product,以便在运行时动态生成它?

您可以动态创建这样的表达式:

// 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);

由于您没有提供您的类型,我创建了自己的类型,因此您的表达式看起来会有点不同

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

问题要求您动态创建表达式,即,当您在编译时不知道属性产品,而只获取属性名称作为输入参数时。您的解决方案是完全静态的,您只是将表达式的声明移动到单独的局部变量表达式,但它并没有改变任何东西,这些变量实际上可能会在发布版本中被编译器优化掉。@Ňuf我不确定您是否正确。OP没有具体说明他所说的动态是什么意思。在我的示例中,OP可以动态地提供表达式,例如通过策略模式。我修改了答案,使用了一个简单的策略。谢谢。这很有效。我之前有过类似的经历。这不是EF,而是NPOCO相关。
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);
        }
    }
}