具有动态条件的Linq Where子句

时间:2019-02-19 23:10:14

标签: c# entity-framework linq

对于API调用,我要提交一个字符串以获取匹配的库存物品。以下内容可按预期工作:

    public IEnumerable<Inventory> GetInventoryByItem(string item)
    {
        return _ctx.Pairs
            .Include(x => x.Attribute)
            .Where(x => (x.Attribute.Item == item));
    }

我的问题是想向函数添加多个条件以获得一些效果:

    public IEnumerable<Inventory> GetInventoryByItem(string[] items)
    {
        return _ctx.Pairs
            .Include(x => x.Attribute)
            .Where(x => foreach(string item in items){ return x.Attribute.Item == item });
    }

上述功能显然不起作用。我知道我可以通过在循环中从外部调用上述函数来获取项目集合,但是我担心的是,当我可以将其合并为一个语句时,会使用多个几乎相同的语句访问数据库。有没有一种有效的方法可以做到这一点?

3 个答案:

答案 0 :(得分:1)

好吧,您可以使用Any

public IEnumerable<Inventory> GetInventoryByItem(string[] items)
{
        return _ctx.Pairs
            .Include(x => x.Attribute)
            .Where(x => items.Any(a=> a == x.Attribute.Item));
  // OR
     return _ctx.Pairs
            .Include(x => x.Attribute)
            .Where(x => items.Contains(x.Attribute.Item));
}

答案 1 :(得分:0)

因此,您需要一个泛型函数,该函数将某个类的对象序列和此类属性的谓词序列作为输入,并希望将包含来自所有输入谓词的输入序列中的那些对象的序列作为输出返回true

例如:

IEnumerable<Person> persons = ...
var predicates = [0] person is born in 1961
                 [1] person is born in Honolulu
                 [2] person is a politician

作为输出,您需要与1961年在檀香山出生的所有政治人物的次序

让我们以此作为扩展方法,因此您可以将其用作LINQ语句。参见extension methods demystified

您要做的是连接Where语句。参数predicateFunc<TSource, bool>中。因此,我们需要一个Func<TSource, bool>序列作为谓词。

static IEnumerable<TSource> Where( this IEnumerable<TSource> source,
    IEnumerable<Func<TSource, bool>> predicates)
{
    // TODO: handle null source and null predicates

    IEnumerable<TSource> result = source;
    foreach (Func<TSource, bool> predicate in predicates)
    {
        result = result.Where(predicate);
    }
    return result;
}

用法示例:

IEnumerable<Person> persons = ...
var honoluluPresidents = persons.Where(new[]
{
     person => person.BirthPlace == "Honolulu",
     person => person.BirthDate.Year == 1961,
     person => person.Job == "politician",
});

简单的漫画卓悦!

答案 2 :(得分:0)

也许您是用.All()来指foreach吗?

public IEnumerable<Inventory> GetInventoryByItems(string[] items)
{
    return _ctx.Pairs
        .Include(x => x.Attribute)
        .Where(x => items.All(item => x.Attribute.Item == item));
}