gpt4 book ai didi

c# - 未定义表达式参数

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

我正在尝试对列表执行查询以使用代码中其他地方设置的表达式立即给出结果,而第二个线程关闭并使用它从 Linq 中的数据库中获取完整的结果集查询。

我知道表达式本身没问题,因为当我通过网络将它发送到服务器端并将它应用于 IQueryable 时,它就会起作用。但是,在客户端应用时会产生以下错误:

System.InvalidOperationException: 'variable 'item' of type 'MissionControlSuite.Shared.Interface.Model.IBox' referenced from scope '', but it is not defined'

执行过滤的代码:

public abstract class GridWithPaging<T> where T : class
{
List<T> _items

public Expression<Func<T, bool>> Filter { get; set; }
public ObservableCollection<IGridFilter<T>> Filters { get; set; }

// more code skipped for breveity

public void FiltersChanged(object sender, EventArgs e)
{
Expression<Func<T, bool>> combined = item => true;
foreach (var filter in Filters)
combined = Expression.Lambda<Func<T, bool>>(
Expression.AndAlso(filter.Expression.Body, combined.Body),
combined.Parameters.Single());

Filter = combined;
NotifyPropertyChanged("Filter");
}

public void AddFilter(IGridFilter<T> filter)
{
Filters.Add(filter);
NotifyPropertyChanged("Filters");
}

private void DoFiltering(int start)
{
var newView = _items.Skip(start);
if(Filter != null)
newView = newView.AsQueryable().Where(Filter);

//some more code that acts on the filtered list
}
}

表达式在别处设置如下:

Expression<Func<IBox, bool>> expression = item => item.BoxId.Contains(v);

var filter = new GridFilter<IBox>()
{
Name = string.Format("{0} contains {1}", Property, Value),
Expression = expression
};

Grid.AddFilter(filter);

最佳答案

这个答案会对你有帮助:Combining two expressions (Expression<Func<T, bool>>)

总结一下:问题是参数虽然名称相同,但与 ParameterExpressioninstance 不同 - 它包含在 comment to that answer 中。

解决方案是使用访问者(从链接的帖子复制代码):

public static Expression<Func<T, bool>> AndAlso<T>(
this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var parameter = Expression.Parameter(typeof (T));

var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter);
var left = leftVisitor.Visit(expr1.Body);

var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter);
var right = rightVisitor.Visit(expr2.Body);

return Expression.Lambda<Func<T, bool>>(
Expression.AndAlso(left, right), parameter);
}



private class ReplaceExpressionVisitor
: ExpressionVisitor
{
private readonly Expression _oldValue;
private readonly Expression _newValue;

public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
{
_oldValue = oldValue;
_newValue = newValue;
}

public override Expression Visit(Expression node)
{
if (node == _oldValue)
return _newValue;
return base.Visit(node);
}
}

另请注意:ORM 提供程序(或您使用的另一个 IQueryable)可能有效,因为它直接将其转换为文本,而执行(Invokeing)此 LambdaExpression 会导致错误,因为它在某种程度上更严格。一些 IQueryable 也可以接受简单的 string 参数并自行解析,这表明它们具有更广泛的可接受输入范围。

关于c# - 未定义表达式参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50964519/

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