将字符串数组作为参数传递给执行linq查询的方法

时间:2016-01-26 21:30:45

标签: c# arrays linq

我可以以及如何将一个字符串数组传递给Linq查询,以便数组的元素提供Where子句,如下面的示例所示?

如果其中一个数组为空,则查询应该仍然有效(只需忽略相应的where子句)。

查询是否会改变,而不是数组一,例如像List<string> brandsList<string> categories等列表?

    private IEnumerable<LatestReading> getLatestReadings(string[] brands, string[] categories)
    {
        return
           from reading in context.Readings
           join product in context.Products
           on reading.ProductId equals product.SkuCode
           // where product.Brand is one or more brands from string[] brands
           // where product.Category is one or more categories from string[] categories
           where reading.Date == lastReadingDate
           select new LatestReading
           {
               ProductId = reading.ProductId,
               Distributor = reading.Distributor,
               Price = reading.Price
           };
    }

2 个答案:

答案 0 :(得分:2)

private IEnumerable<LatestReading> getLatestReadings(string[] brands, string[] categories)
    {
        return
           from reading in context.Readings
           join product in context.Products
           on reading.ProductId equals product.SkuCode
           where (brands.Length == 0 || brands.Contains(product.Brand))
           where (categories.Length == 0 || categories.Contains(product.Category))
           where reading.Date == lastReadingDate
           select new LatestReading
           {
               ProductId = reading.ProductId,
               Distributor = reading.Distributor,
               Price = reading.Price
           };
    }

答案 1 :(得分:2)

当然关键是使用Contains。正如您从链接中看到的,它适用于IEnumerable<T>,因此应回答问题的第二部分 - 您可以传递任何IEnumerable<string>,包括string[]List<string>等。

虽然您可以使用another anwer中的技术,但它会生成一个奇怪的SQL查询(检查出来)。无论何时需要动态过滤,更好的方法是使用LINQ方法语法和动态Where链,就像这样

// Products subquery with optional filters
var products = context.Products.AsQueryable();
if (brands.Any())
    products = products.Where(product => brands.Contains(product.Brand);
if (categories.Any())
    products = products.Where(product => categories.Contains(product.Category);
// Now the main query (just use products instead of context.Products)
return
    from reading in context.Readings
    join product in products
        on reading.ProductId equals product.SkuCode
    where reading.Date == lastReadingDate
    select new LatestReading
    {
        ProductId = reading.ProductId,
        Distributor = reading.Distributor,
        Price = reading.Price
    };