none
Where clause doesn't limit the group clause? RRS feed

  • Question

  • I have the following code:

     from call in allClosedCalls
     where (call.ClosedDate.HasValue && //also limit?:
             (lastMonths > 0) ?
             (call.ClosedDate.Value.Year >= DateTime.Now.AddMonths(-lastMonths + 1).Year &&
              call.ClosedDate.Value.Month >= DateTime.Now.AddMonths(-lastMonths + 1).Month)
              : true)
             group call by //dates
              new
                  {
                        Month = call.ClosedDate.Value.Month,
                       Year = call.ClosedDate.Value.Year
                   }
            into d

     

    close date is nullable.

    when I run thsi I get exception that says "Nullable object must have a value."

    why is date? the where filter  should filter only the calls with closedate and then group them by date shouldn't it?


    Tuesday, August 9, 2011 9:35 AM

Answers

  • Hi liorba,

     

    Wow man, this one was tricky :)

     

    The problem is caused because of the C# operator precedence order.

    It tries to find out if this one is true 

    call.ClosedDate.HasValue && (lastMonths > 0)

    if this is false it will return with true. This means if the lastMonth is less than 1 then the records will be included even if the close date is null.

    Because of this the group by is throwing an exception where it calls the CloseDate.Value where the CloseDate is null.

     

    the solution is simple, just add brackets:

     

     from call in allClosedCalls
     where (call.ClosedDate.HasValue && //also limit?:
      ((lastMonths > 0) ?
       (call.ClosedDate.Value.Year >= DateTime.Now.AddMonths(-lastMonths + 1).Year &&
       call.ClosedDate.Value.Month >= DateTime.Now.AddMonths(-lastMonths + 1).Month)
       : true))
       group call by //dates
       new
        {
         Month = call.ClosedDate.Value.Month,
         Year = call.ClosedDate.Value.Year
        }
      into d
    

    HTH

     

     

     


    Regards, Peter

    //If a post answers your question, please click "Mark As Answer".
    //Also if a post seems to be helpful, please click "Mark as Helpful" on that post.
    • Marked as answer by liorba Wednesday, August 10, 2011 12:55 PM
    Wednesday, August 10, 2011 12:37 PM
  • You are welcome.

     

    the answer is here

    http://msdn.microsoft.com/en-us/library/aa691323%28v=vs.71%29.aspx

     

    The && is stronger than the ?:

    so when you write

    A && B ? C : D

    then it will became

    (A && B) ? C : D

    and here you wanted to write

    A && (B ? C : D)

     


    Regards, Peter

    //If a post answers your question, please click "Mark As Answer".
    //Also if a post seems to be helpful, please click "Mark as Helpful" on that post.
    • Marked as answer by liorba Wednesday, August 10, 2011 1:01 PM
    Wednesday, August 10, 2011 12:59 PM

All replies

  • Hi liorba,

     

    Wow man, this one was tricky :)

     

    The problem is caused because of the C# operator precedence order.

    It tries to find out if this one is true 

    call.ClosedDate.HasValue && (lastMonths > 0)

    if this is false it will return with true. This means if the lastMonth is less than 1 then the records will be included even if the close date is null.

    Because of this the group by is throwing an exception where it calls the CloseDate.Value where the CloseDate is null.

     

    the solution is simple, just add brackets:

     

     from call in allClosedCalls
     where (call.ClosedDate.HasValue && //also limit?:
      ((lastMonths > 0) ?
       (call.ClosedDate.Value.Year >= DateTime.Now.AddMonths(-lastMonths + 1).Year &&
       call.ClosedDate.Value.Month >= DateTime.Now.AddMonths(-lastMonths + 1).Month)
       : true))
       group call by //dates
       new
        {
         Month = call.ClosedDate.Value.Month,
         Year = call.ClosedDate.Value.Year
        }
      into d
    

    HTH

     

     

     


    Regards, Peter

    //If a post answers your question, please click "Mark As Answer".
    //Also if a post seems to be helpful, please click "Mark as Helpful" on that post.
    • Marked as answer by liorba Wednesday, August 10, 2011 12:55 PM
    Wednesday, August 10, 2011 12:37 PM
  • Thank alot! :)

    why is that? isn't  the && operator short circuit and if the first expression is false shouldn't the entire expression be evaluated to false with the second part not even evaluated?

    Wednesday, August 10, 2011 12:55 PM
  • You are welcome.

     

    the answer is here

    http://msdn.microsoft.com/en-us/library/aa691323%28v=vs.71%29.aspx

     

    The && is stronger than the ?:

    so when you write

    A && B ? C : D

    then it will became

    (A && B) ? C : D

    and here you wanted to write

    A && (B ? C : D)

     


    Regards, Peter

    //If a post answers your question, please click "Mark As Answer".
    //Also if a post seems to be helpful, please click "Mark as Helpful" on that post.
    • Marked as answer by liorba Wednesday, August 10, 2011 1:01 PM
    Wednesday, August 10, 2011 12:59 PM
  • good to know!

    thanks again! :)

    Wednesday, August 10, 2011 1:00 PM