将参数传递给实体框架中的可重用表达式
本文关键字:表达式 参数传递 实体 框架 | 更新日期: 2023-09-27 18:37:26
我想声明和重用表达式,并按变量y过滤。在一种方法中,我有如下内容:
Expression<Func<Item, int, bool>> exFilter = (x, y) => x.Item.Id == y;
此外,在代码中,我尝试使用声明的表达式(exFilter)
return context.Item.Select(x => new { data = exFilter.Where(exFilter))
问:如何将参数传递给 exFilter?我想选择按列表(x)中的每个项目过滤。
这只是我试图弄清楚的一个示例。问题和查询要大得多,也复杂得多。
可以使用 LinqKit 重用您拥有的表达式。下面是一个示例:
var result =
context.Item //The DbSet
.AsExpandable() //This method is defined in LinqKit and allows for expression expansion
.Where(x => exFilter.Invoke(x, 2)) //LinqKit will know how to translate this into an expression
.ToList();
我在这里使用值 2 作为示例。
你可以像这样重写代码:
Expression<Func<Item, bool>> exFilter(int y){ return (x) => x.item.Id == y;}
并像这样使用它:
int paramY = 456;
return context.Item.Select(exFilter(paramY))
你可以尝试这样的事情:
public class Item
{
public Item(String str, Int32 @int)
{
this.StrValue = str;
this.IntValue = @int;
}
public String StrValue { get; }
public Int32 IntValue { get; }
public override string ToString() =>
$"{this.IntValue} = '{this.StrValue}'";
}
public static class ExpressionExtensions
{
public static Expression<Func<TItem, TResult>> Curry<TItem, TCurry, TResult>(
this Expression<Func<TItem, TCurry, TResult>> function,
TCurry value)
{
if (function == null)
throw new ArgumentNullException(paramName: nameof(function));
var itemParameter = Expression.Parameter(typeof(TItem));
var valueConstant = Expression.Constant(value);
return Expression.Lambda<Func<TItem, TResult>>(
Expression.Invoke(
function,
new Expression[]
{
itemParameter,
valueConstant
}),
new[] { itemParameter });
}
}
。
var items = new[]
{
new Item("one", 1),
new Item("two", 2),
new Item("two again", 2),
};
Expression<Func<Item, Int32, Boolean>> predicate = (item, intValue) =>
item.IntValue == intValue;
var curriedPredicate = predicate.Curry(2);
var filtered = items
.AsQueryable<Item>()
.Where(curriedPredicate)
.ToArray();
foreach (var item in filtered)
{
Console.WriteLine(item);
}