0

I created a simple setup to try to write the appropriate Linq statement in C#.

I'm trying to return a BOOLEAN that checks the following

  1. Example 1: Where Product title = 'ERDSIC' and Property title = 'size' and val = 1001 (should return TRUE)
  2. Example 2: Where Product title = 'ERDCON' and Property title = 'size' and val = 1001 (should return 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.

How can I write a Linq statement that will fit the following criteria for Example 1 and Example 2?

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







  }
}
0

2 Answers 2

3

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

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

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
Sign up to request clarification or add additional context in comments.

1 Comment

.Where(..).Any() should stop enumerating the where criteria and the underlying collection after the first result. The performance should be practically identical.
0

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

1 Comment

Did you test this before posting? CS1061 'List<Property>' does not contain a definition for 'title' and no extension method 'title' accepting a first argument of type 'List<Property>' could be found.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.