如何解决使用 Expression.Lambda<Func<>>()
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 举报,一经查实,本站将立刻删除。