gpt4 book ai didi

c# - Linq表达式(curry参数)传递给linq to entities

转载 作者:太空宇宙 更新时间:2023-11-03 21:14:19 24 4
gpt4 key购买 nike

所以我能够完成第一步,这只是允许某人使用表达式来获取我可以与字符串进行比较的属性。

现在我正试图将它提升到一个新的水平,我希望人们能够执行“where”子句,我将代入要比较的值。基本用例是我们的 API 接受一个名为 ?filterBy:AddressState:VA 的查询参数。

我正在尝试创建一些能够将子句一般附加到 IQueryable 的东西。基本上每个 API 都需要创建一个键/表达式 的字典,它将查找属性以比较 filterBy 的右侧,例如VA.. 这是我目前所拥有的,但它目前因错误而崩溃

我试图让某人定义:

public Dictionary<string, Expression<Func<User, string, bool>>> FILTER_BY = new Dictionary<string, Expression<Func<User, string, bool>>>()  
{
{ "addressstate", (x,inputValue) => x.Address.State == inputValue},
};

然后可以在api调用中做:

baseQ = baseQ.FilterBy(filterBy, FILTER_BY);

但这就是我被困的地方。我试图弄清楚如何用字符串替换 inputValue(在本例中)。

归根结底,我希望能够定义:

(x, inputValue) => x.Address.State == inputValue

我想写一些东西来用一个新的表达式替换上面的内容以传递给 linq to entities

(x) => x.Address.State == "Va"

扩展方法:

public static IQueryable<T> FilterBy<T, CompareMe>(this IQueryable<T> query, string filterBy, Dictionary<string, Expression<Func<T, CompareMe, bool>>> filterExpressions)
{
if (!string.IsNullOrEmpty(filterBy))
{
//parse on ':' throw argument if there is not two.
var split = filterBy.Split(':');
var key = split[0];
var right = string.Join("", split.Skip(1));


var expression =filterExpressions.FirstOrDefault(x=>x.Key == key.ToLower());
if (expression.Key != null)
{
var parameter = Expression.Parameter(typeof(T), expression.Value.Parameters[0].Name);

Expression body = new ReplaceVisitor<string>(expression.Value.Parameters[1], right).Visit(expression.Value.Body);
var lambda = Expression.Lambda<Func<T, bool>>(body, parameter);

return query.Where(lambda);

}
}

}

这是 ReplaceVisitor:

  class ReplaceVisitor <CompareMe> : ExpressionVisitor
{
private CompareMe _value;


private ParameterExpression _parameter;

public ReplaceVisitor(ParameterExpression parameter, CompareMe value)
{
_parameter = parameter;
_value = value;
}

protected override Expression VisitParameter(ParameterExpression node)
{
if (node.Name == _parameter.Name)
{
return Expression.Constant(_value);
}
return node;
}
}

我正在对实体使用 linq,所以无论我在那个 where 子句中放入什么,都需要安全地转换为 sql。

我得到的错误:

ExceptionMessage: "The parameter 'x' was not bound in the specified LINQ to Entities query expression.",

最佳答案

所以最终我解决了它。我基本上需要使用 Visitor 将参数替换为常量,然后将 original 参数传递给 Expression.Lambda

解决方案是改变:

var parameter = Expression.Parameter(typeof(T), expression.Value.Parameters[0].Name);

Expression body = new ReplaceVisitor<string>(expression.Value.Parameters[1], right).Visit(expression.Value.Body);

var lambda = Expression.Lambda<Func<T, bool>>(body, parameter);

收件人:

Expression body = new ReplaceVisitor<string>(expression.Value.Parameters[1], right).Visit(expression.Value.Body);
var lambda = Expression.Lambda<Func<T, bool>>(body, expression.Value.Parameters[0]);

关于c# - Linq表达式(curry参数)传递给linq to entities,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35484649/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com