【问题标题】:Variable amount of OR, AND conditions on a lamba WHERE clauseLamba WHERE 子句上的可变数量的 OR、AND 条件
【发布时间】:2020-03-27 23:24:21
【问题描述】:

我看过类似的问题,但没有人能够真正回答我的问题。 我想要做的就是使用lamba 进行选择,但诀窍是,选择有可变数量的OR/AND 条件。我的函数接收一个 AND 条件列表,它应该根据它进行选择。

这是我现在拥有的,它最多支持 10 个 AND 条件作为字符串传递以进行比较,但是这段代码很糟糕。实际上它应该能够接受未定义/可变数量的条件。

不知道该怎么做。。 ProductTags 是标签列表。如果产品具有所有标签,则返回。

public static List<product> FilterProductsByTagsAll(List<string> tags)
{
    List<product> products = new List<product>();
    switch (tags.Count)
    {
        case 1:
            products = Database.Products.Values.Where(i => i.ProductTags != null
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[0]).Any()).ToList();
            break;
        case 2:
            products = Database.Products.Values.Where(i => i.ProductTags != null
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[0]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[1]).Any()).ToList();
            break;
        case 3:
            products = Database.Products.Values.Where(i => i.ProductTags != null
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[0]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[1]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[2]).Any()).ToList();
            break;
        case 4:
            products = Database.Products.Values.Where(i => i.ProductTags != null
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[0]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[1]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[2]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[3]).Any()).ToList();
            break;
        case 5:
            products = Database.Products.Values.Where(i => i.ProductTags != null
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[0]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[1]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[2]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[3]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[4]).Any()).ToList();
            break;
        case 6:
            products = Database.Products.Values.Where(i => i.ProductTags != null
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[0]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[1]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[2]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[3]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[4]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[5]).Any()).ToList();
            break;
        case 7:
            products = Database.Products.Values.Where(i => i.ProductTags != null
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[0]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[1]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[2]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[3]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[4]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[5]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[6]).Any()).ToList();
            break;
        case 8:
            products = Database.Products.Values.Where(i => i.ProductTags != null
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[0]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[1]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[2]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[3]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[4]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[5]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[6]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[7]).Any()).ToList();
            break;
        case 9:
            products = Database.Products.Values.Where(i => i.ProductTags != null
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[0]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[1]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[2]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[3]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[4]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[5]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[6]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[7]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[8]).Any()).ToList();
            break;
        case 10:
            products = Database.Products.Values.Where(i => i.ProductTags != null
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[0]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[1]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[2]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[3]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[4]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[5]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[6]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[7]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[8]).Any()
                                                        && i.ProductTags.Where(i => i != null && i.Tag_name == tags[9]).Any()).ToList();
            break;
        default:
            break;
    }

    return products;
}

感谢您的帮助。

【问题讨论】:

  • 你一定要使用 LINQ 吗?
  • 呃,仅仅迭代tags而不是根据限制条件对循环步骤进行硬编码不是更容易吗?
  • 好的,所以我的 C# 和 LINQ 都很差。我知道基础知识,但没有设置来测试它,但似乎你只是想要products = Database.Products.Values.Where(i =&gt; i.ProductTags != null).Where(i =&gt; tags.Any(tag =&gt; tag == i.Tag_name)).ToList();
  • 我知道迭代会更容易,但我真的在寻找基于 Lamba 或 LINQ 的解决方案。
  • @Tehavatar 嗨,回答成功了吗?

标签: c# .net lambda


【解决方案1】:

试试这个查询:

var allTagsProds = Database.Products.Values.Where(p => p.ProductTags != null && p.ProductTags.Select(pt => pt.Tag_name).Intersect(tags).Count() == tags.Count());

对于每个产品,它会选择产品标签名称,然后将它们与标签列表相交。这会生成与标签列表匹配的产品标签名称列表。

然后它将这个列表的计数与标签列表的计数进行比较,如果它们相同,则该产品具有所有标签。然后返回这些。

使用硬编码模型的示例:

public class Tag {
    public string Tag_name {get; set;}
}

public class Product {

    public ICollection<Tag> ProductTags {get; set;} 
    public string Name {get; set;}
    }

public class Program
{
    public static void Main()
    {
        List<string> tags = new List<string> {"a","b","c","d","e","f"};

        var prodTags = new List<Tag>() {
            new Tag() {Tag_name = "a"},
            new Tag() {Tag_name = "b"},
            new Tag() {Tag_name = "c"},
            new Tag() {Tag_name = "d"}
        };

        var prodTags2 = new List<Tag>() {
            new Tag() {Tag_name = "a"},
            new Tag() {Tag_name = "b"},
            new Tag() {Tag_name = "c"},
            new Tag() {Tag_name = "d"},
            new Tag() {Tag_name = "e"},
            new Tag() {Tag_name = "f"}
        };

        var products = new List<Product>() {
            new Product() { Name="Prod1", ProductTags = prodTags },
            new Product() {  Name="Prod2",ProductTags = prodTags2 }
        };
        var allTagsProds = products.Where(p => p.ProductTags != null && p.ProductTags.Select(pt => pt.Tag_name).Intersect(tags).Count() == tags.Count());

        foreach(var prod in allTagsProds)
        {
            //Writes "Prod2"
            Console.WriteLine(prod.Name);
        }
    }
}

【讨论】:

    猜你喜欢
    • 2015-09-11
    • 2021-02-02
    • 1970-01-01
    • 2017-06-11
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多