微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 Expression.Lambda<Func<>>()

如何解决使用 Expression.Lambda<Func<>>()

我有一个 linq 查询,如下所示:

var query = _appDbContext.Persons
                .Where(p => p.Id == 123)
                .Select(lambda)
                .ToList();

我使用 lambda 是因为我的 select 语句中有一个变量。拉姆达:

var wantedData = "Adress";

var x = Expression.Parameter(typeof(Person),"x");
var body = Expression.PropertyOrField(x,wantedData);
var lambda = Expression.Lambda<Func<Person,Adress>>(body,x);

查询将返回 ID 为 123 的人的地址。假设我想接收此人的所有订阅而不是地址。由于 lambda 语句中的“地址”,仅设置 wantedData = "Subscription" 将不起作用。所以我正在寻找一种方法来使用变量来更改 lambda 语句中的“地址”。

我尝试了以下方法,但显然不起作用。

var lambda = Expression.Lambda<Func<Person,wantedData>>(body,x);

有没有办法做到这一点?

解决方法

好的,我设法创建了一个将表达式作为参数的通用查询方法。

编辑:这将接收一个字符串值,并尝试将它与您的 Person 类上的现有属性进行匹配。

private IEnumerable<TResult> GetPersonData<TResult>(Expression<Func<Person,TResult>> selectExpression)
{
    return _dbContext.Persons
            // .Where(filter)
        .Select(selectExpression)
        .ToList();
}

public IEnumerable<object> GetData(string dataPropertyName)
{
    switch(dataPropertyName) {
         case nameof(Person.Address): return GetPersonData(p => p.Address);
         case nameof(Person.Subscription): return GetPersonData(p => p.Subscription);
         // other cases
         default: throw new InvalidArgumentException("Invalid property name");
    }
}

请注意,此代码只是现场编写的示例,可能无法直接复制粘贴

,

我制作了类似于 OrderBy 的东西,并根据您的选择对其进行了一些调整。这仅在您知道返回类型时才有效。 您可以使用以下代码创建扩展方法:

public static IQueryable<TResult> Select<T,TResult>(this IQueryable<T> source,string propertyName)
{
    var prop = typeof(T).GetProperties()
        .FirstOrDefault(x => x.Name.ToUpper() == propertyName.ToUpper());
    ParameterExpression pe = Expression.Parameter(typeof(T),"x");
    MemberExpression body = Expression.Property(pe,prop.Name);

    LambdaExpression lambda = Expression.Lambda(body,new ParameterExpression[] { pe });

    MethodCallExpression selectCallExpression = Expression.Call(
        typeof(Queryable),"Select",new Type[] { source.ElementType,prop.PropertyType },source.Expression,lambda);
    return source.Provider.CreateQuery<TResult>(selectCallExpression);
}

这样,你可以像这样使用它:

var query = _appDbContext.Persons
                .Where(p => p.Id == 123)
                .Select<Person,string>(wantedData)
                .ToList();

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?