C# linq query aggregate nullable boolean

how to check null value in linq query in c#
linq check for null in where clause
handle null in linq select c#
handle null values in linq select
how to check null value in lambda query in c#
linq select nullable int
linq select where not null or empty
linq: adding where clause only when a value is not null

I'd like to use linq to aggregate a nullable bool following the logic:

  • If all is true then true;
  • if all is false then false;
  • else null

Here is my code, I couldn't get the bool aggregate.

class T1
{
  public string property1{get;set;}
  public string property2{get;set;}
  public bool? BoolProperty{get;set;}
}

///initialize a list<T1> t2 with values......
List<T1> t2 = new List<T1>();
t2.Add(new T1() 
        {
            property1="hello",
            property2="world",
            BoolProperty=true
        });
t2.Add(new T1() 
        {
            property1="hello",
            property2="world",
            BoolProperty=false
        });

List<T1> t1 = t2.GroupBy(g => new
        {
            g.property1,
            g.property2               
        })
        .Select(g => new T1
        {
            property1 = g.Key.property1,
            property2 = g.Key.property2,                
            BoolProperty = ////can someone help? if all object in t2 are true, true; if all object in t2 are false, false; else null
 ///in this case i am expecting a null
        }).ToList();

So t1 will be "hello", "world", null; Thanks

Put this in your code,

List<T1> t1 = t2.GroupBy(g => new
        {
            g.property1,
            g.property2               
        })
        .Select(g => new T1
        {
            property1 = g.Key.property1,
            property2 = g.Key.property2,                
            BoolProperty =  g.GroupBy(grp => grp.BoolProperty).Count() > 1 ? null : g.Select(g_val=>g_val.BoolProperty).First()
        }).ToList();

Handle null values in query expressions (LINQ in C#), See also. Nullable<T> � Language Integrated Query (LINQ) � Nullable value types � The null value cannot be assigned to a member with type System.Boolean which is a non-nullable value type. so how can i set the Validate Field when it Contain Null in db. i want to set it to be true when it has false or null.

How about this?

BoolProperty = g.All(p => p.BoolProperty.GetValueOrDefault())
    ? true
    : (g.All(p => !(p.BoolProperty ?? true))
        ? (bool?)false
        : null)
            }).ToList();

How Handle Nullable bool values in Linq, I have to Hide and show some fields by getting the bit values from database using linq query. here is some Sum(x => x. From what I understand IsCoin is nullable bool (bool? or Nullable<bool>) then you can check on null,� The conditional expression with null in this example works because Products.CategoryID is of type int? which is shorthand for Nullable<int>. Example. In a join clause, if only one of the comparison keys is a nullable value type, you can cast the other to a nullable value type in the query expression.

I'd suggest the following solution. It requires the use of MoreLINQ.

List<T1> t1 = t2.GroupBy(g => new
{
    g.property1,
    g.property2
}).Select(groupedItems =>
    {
        // My code starts here
        bool? result = null;
        var bools = groupedItems
            .OrderBy(z => z.BoolProperty)
            .TagFirstLast((z, first, last) => new { z, firstOrLast = first || last })
            .Where(z => z.firstOrLast)
            .Select(z => z.z.BoolProperty).ToList();

        if (bools.Count == 0)
        {
            // Do nothing
        }
        else if (bools.First() == bools.Last())
        {
            result = bools.First();
        }
        // My code ends here

        return new T1
        {
            property1 = groupedItems.Key.property1,
            property2 = groupedItems.Key.property2,
            BoolProperty = result
        };
    }).ToList();

The key bit is the use of OrderBy, to ensure that the true, false and null values are adjacent (i.e. grouped together in order).

Then TagFirstLast allows us to ignore everything other than the first and last entries (which is all we need).

Then we check whether the first and last entry are the same - if they are, use that value (whether it be null or true or false - either way it fits the requirements).

Otherwise, use null (since that would be your else condition).

LINQ Min, LINQ Min method usage examples. Min for Nullable Numeric Types LINQ query expression to get minimal string length using selector. LINQ Count - counts number of items in a collection (result type is Int32) LINQ LongCount - counts number of items in a collection (result type is Int64) LINQ Average - computes average value of numeric collection; LINQ Aggregate - applies aggregate function to a collection; C# List - illustrative examples of all List<T> methods

This can all be done by linq, but that would propbably never be the most efficient way because you either need to enumerate more than once or other shenenigans. Sometimes best approach ist plain old code.

public static bool? CantFindAgoodName(IEnumerable<bool?> items)
{ 
     bool? check = null;
     bool first = true;
     foreach(var item in items)
     {
         if(first)
         {
            check = item;
            first = false;
         }
         else if(check != item) 
            return null;
     }
     return check;
}

Then just write

BoolProperty = CantFindAGoodName(g)

If you really wanna do it with standard Linq, it can be done with a single iteration, but its neither efficient (because it doesnt break imediately) nor beatuiful...

BoolProperty = g.Aggregate(-1,
              (n, b) => n == -1
                ? (b == null ? 0 : (b.Value ? 1 : 2))
                : (n == (b == null ? 0 : (b.Value ? 1 : 2)) ? n : -2), 
              i => i == -2 ? default(bool?) : i == 1);

So how does it work?

-1  = seed
 0  = null
 1  = true
 2  = false
-2  = different values aka null

While the value is either the first or equals its predecessor, it keeps getting forwareded. So if the sequence consists purely of the same element, that will get forwarded. If its different however, -2 will get forwarded, which will allways be different to any other element remaining. In the end the second lambda just transforms the result back into a bool?

LINQ Max, LINQ Max method usage examples. Max for Nullable Numeric Types LINQ query expression to get maximal string length using selector. LINQ Count - counts number of items in a collection (result type is Int32) LINQ LongCount - counts number of items in a collection (result type is Int64) LINQ Average - computes average value of numeric collection; LINQ Aggregate - applies aggregate function to a collection; C# List - illustrative examples of all List<T> methods; C# foreach

You can use

var allTrue = t2.All(x=>x.BoolProperty == true);
var allFalse = t2.All(x=>x.BoolProperty == false);
var anyNull = t2.Any(x=>x.BoolProperty.HasValue == false);

before grouping.

Aggregate, The True LINQ Aggregator Operator, The Sum extension method returns the sum of elements sequence. These elements can be null. The Sum operator has 20 overloads in 2 groups. This tutorial explains how to create a dynamic LINQ query in C#. Using the Predicate Builder we can create LINQ to SQL dynamic query and Query with Entity Framework is easy. This concept was first implement by albahari. Later this concept extended by Monty’s Gush as Universal PredicateBuilder. Description

LINQ – don't be afraid of Aggregate – Hryniewski.NET, Aggregate is one of the most fun and powerful methods in LINQ. I hope that after reading this post you will understand Aggregate a bit more, know when to This is pretty simple example so let's do the same with Aggregate. C# TCompareBy> compareBy, IComparer<TCompareBy> comparer = null). IEnumerable.GetEnumerator() Returns an enumerator that can iterate through the associated IEnumerable<T> collection, or, if it is null, through the collection that results from rewriting the associated expression tree as a query on an IEnumerable<T> data source and executing it.

LINQ Queries / Aggregate / Essential C#, LINQ Queries / Aggregate / Essential C#. Aggregate Applies an accumulator function over a sequence. int[] intList = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 38 Nullable types. Most of the LINQ set methods are supported in LINQ to Entities queries, with the exception of those that use an EqualityComparer<T>. For more information, see Standard Query Operators in LINQ to Entities Queries. The following table lists the supported and unsupported set methods.

generated code - Linq to LLBLGen Pro, general usage, Linq queries against a database, using the LinqMetaData queryable object can still NET compiler doesn't generate any Expression tree from the Aggregate coalesce statements on these boolean expressions if it detects a Nullable(Of T)� For a normal boolean, no, since it's superfluous. However, for a nullable boolean, this is relevant. nullableBool == true is basically testing for nullableBool != false && nullableBool != null (and it's this second part that makes it useful and therefore not superfluous) – Flater Sep 29 '17 at 12:54

Comments
  • I wish I can choose multiple answers. Thank you all for your help!
  • this seems to be working....but I am not sure why someone downvoted this with no comments?
  • Yeah not sure why it was downvoted either! Accept if it worked for you! :)
  • I am waiting for that comments while do more tests
  • The one downside of this approach I see is that the All must iterate over the data set twice. Not a huge downside, admittedly.
  • p.BoolProperty.HasValue && !p.BoolProperty.Value could perhaps be simplified to !(p.BoolProperty ?? true) and p.BoolProperty.HasValue && p.BoolProperty.Value to p.BoolProperty ?? false.
  • Elegant and uses less resources. Wow, answers are just getting better
  • So what if the input list is null, false, false, false? It would return False, while the expected return is null. Correct me if I am wrong....thanks
  • @Heisenberg You are wrong. Why dont you just test it... dotnetfiddle.net/1tS3sv
  • I was testing the function CantFindAGoodName, it returns false....dotnetfiddle.net/aqQpqy