简体   繁体   English

C# Linq 在对象列表中查找对象列表中的值

[英]C# Linq Find value inside list of objects inside a list of objects

I created a simple setup to try to write the appropriate Linq statement in C#.我创建了一个简单的设置来尝试在 C# 中编写适当的 Linq 语句。

I'm trying to return a BOOLEAN that checks the following我正在尝试返回检查以下内容的 BOOLEAN

  1. Example 1: Where Product title = 'ERDSIC' and Property title = 'size' and val = 1001 (should return TRUE)示例 1:其中 Product title = 'ERDSIC' and Property title = 'size' and val = 1001 (应该返回 TRUE)
  2. Example 2: Where Product title = 'ERDCON' and Property title = 'size' and val = 1001 (should return FALSE)示例 2:其中 Product title = 'ERDCON' and Property title = 'size' and val = 1001 (应该返回 FALSE)

I attempted my own Linq statement which is producing a boolean inside an object, but I can't get it to return an actual boolean.我尝试了我自己的 Linq 语句,该语句在 object 内产生了 boolean,但我无法让它返回实际的 Z823ZA5A208

How can I write a Linq statement that will fit the following criteria for Example 1 and Example 2?如何编写符合示例 1 和示例 2 的以下标准的 Linq 语句?

var result = listProducts
               .Where(a => a.title == "ERDSIC").Select(
                  a => a.listProperties.Where(b => b.title == "size").Select(
                      c => c.listValues.Where(d => d.val == 1001).Any()
                  )
               );

    Console.WriteLine(result.ToString()); 
    //returns:  System.Linq.Enumerable+WhereSelectListIterator`2[Program+Product,System.Collections.Generic.IEnumerable`1[System.Boolean]]

TEST PROGRAM:测试程序:

using System.Collections.Generic;
using System;
using System.Linq;

public class Program
{
  public class Value {
    public int id {get;set;}
    public int val {get;set;}
  }

  public class Property {
    public int id {get;set;}    
    public string title {get;set;}
    public List<Value> listValues {get;set;}
  }


  public class Product {
    public int id {get;set;}
    public string title {get;set;}
    public List<Property> listProperties {get;set;}
  }

  public static void Main()
  {
    List<Product> listProducts = new List<Product> 
    {
        new Product { 
            id = 1, 
            title = "ERDCON",
            listProperties = new List<Property> {
                new Property {
                    id = 1, 
                    title = "voltage",
                    listValues = new List<Value> {
                        new Value {id = 1, val = 7},
                        new Value {id = 2, val = 12},
                        new Value {id = 3, val = 21}
                    }
                },
                new Property {
                    id = 2, 
                    title = "size",
                    listValues = new List<Value> {
                        new Value {id = 4, val = 101},
                        new Value {id = 5, val = 102},
                        new Value {id = 6, val = 103},
                        new Value {id = 7, val = 104}
                    }
                }
            }
        },

        new Product { 
            id = 14, 
            title = "ERDSIC",
            listProperties = new List<Property> {
                new Property {
                    id = 31, 
                    title = "direction",
                    listValues = new List<Value> {
                        new Value {id = 18, val = 0},
                        new Value {id = 21, val = 1}
                    }
                },
                new Property {
                    id = 1, 
                    title = "size",
                    listValues = new List<Value> {
                        new Value {id = 68, val = 1001},
                        new Value {id = 71, val = 1004}
                    }
                }
            }
        }       
    };


    //Example 1: Check if List<Product> contains "Product Title='ERDSIC', "Property title='size', and "val = 1001"
    //result should return TRUE



    //Example 2: Check if List<Product> contains "Product Title='ERDCON', "Property title='size', and "val = 1001"
    //result should return FALSE







  }
}

You should replace the Where method with Any mostly, because Where returns filtered sequence, when Any determines whether any element of a sequence satisfies a condition您应该主要用Any替换Where方法,因为Where返回过滤后的序列,当Any确定序列的任何元素是否满足条件时

var result = listProducts.Any(product =>
    product.title == "ERDSIC" && product.listProperties.Any(property =>
        property.title == "size" && property.listValues.Any(v => v.val == 1001)));

However, it's better to wrap this code into method, like extension one, and call with different arguments但是,最好将此代码包装到方法中,如扩展一,并使用不同的 arguments 调用

public static class Ext
{
    public static bool HasTitleAndSize(this IEnumerable<Product> products, string title, int size)
    {
        return products.Any(product =>
            product.title == title && product.listProperties.Any(property =>
                property.title == "size" && property.listValues.Any(v => v.val == size)));
    }
}

And call in the following way并通过以下方式调用

var result = listProducts.HasTitleAndSize("ERDSIC", 1001); //returns true
result = listProducts.HasTitleAndSize("ERDCON", 1001); //returns false

Trying to mimic your style, first query may look like:尝试模仿您的风格,第一个查询可能如下所示:

var result = listProducts
    .Where(a => a.title == "ERDSIC")
    .SelectMany(a => a.listProperties)
    .Where(b => b.title == "size")
    .SelectMany(c => c.listValues)
    .Where(d => d.val == 1001)
    .Any();

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

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