繁体   English   中英

将参数传递给实体框架中的可重用表达式

[英]Pass a parameter to the reusable Expression in a Entity Framework

我想通过变量 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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM