简体   繁体   English

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

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

I want to declare and reuse Expression with filter by variable y.我想通过变量 y 声明和重用带有过滤器的表达式。 In a method I have something like following:在一种方法中,我有如下内容:

Expression<Func<Item, int, bool>> exFilter = (x, y) => x.Item.Id == y;

Further on, in a code I'm trying to use declared expression (exFilter)进一步,在代码中我试图使用声明的表达式(exFilter)

return context.Item.Select(x => new { data = exFilter.Where(exFilter))

Q: How do I pass parameter to the exFilter?问:如何将参数传递给 exFilter? I want to do select filtered by every item in a list(x).我想选择按列表(x)中的每个项目过滤。

This is just a sample what I'm trying to figure out.这只是我试图弄清楚的一个示例。 The problem and query is much bigger and complicated.问题和查询更大更复杂。

You can use LinqKit to reuse the expression that you have.您可以使用LinqKit重用您拥有的表达式。 Here is an example:下面是一个例子:

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();

I am using the value 2 here as an example.我在这里使用值 2 作为示例。

You can rewrite you code like this:你可以像这样重写你的代码:

Expression<Func<Item, bool>> exFilter(int y){ return (x) => x.item.Id == y;}

And use it like this:并像这样使用它:

int paramY = 456;
return context.Item.Select(exFilter(paramY))

You can try something like this:你可以尝试这样的事情:

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