Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boolean shortcircuit evaluation in Linq lambda expression

I have the following Linq lambda expression:

private IEnumerable<SubjectSelectorSubjectGroup> GetSubjectList()
{
    User user = db.Users.Find(WebSecurity.CurrentUserId);
    return db.RequiredSubjects.Where(r => !r.Subject.Name.Contains("Home"))
                              .GroupBy(r => r.Subject)
                              .OrderByDescending(r => r.Count())
                              .Select(r => new SubjectSelectorSubjectGroup()
                              {
                                  SubjectId = r.Key.SubjectId,
                                  SubjectName = r.Key.Name,
                                  IsInFavourites = HttpContext.Current.Request.IsAuthenticated &&
                                                  (user.Elective1 != null && user.Elective1.SubjectId == r.Key.SubjectId ||
                                                   user.Elective2 != null && user.Elective2.SubjectId == r.Key.SubjectId ||
                                                   user.Elective3 != null && user.Elective3.SubjectId == r.Key.SubjectId),
                                  Occurrences = r.Count()
                              });
}

When the user is not logged in then the user variable in this function is null. This should not be a problem becuase short-circuit boolean evaluation should deal with this. The problem is, it doesn't! Instead, a System.NullReferenceException is thrown.

When the user is null HttpContext.Current.Request.IsAuthenticated returns false. I have checked this by commenting out the bracketed section that references the user variable, and then expression evaluates correctly.

Does anyone know why Linq to Sql tries to dereference the user variable in this situation when it shouldn't actually be necessary? Does anyone have a work around for this issue?

like image 699
BruceHill Avatar asked Jan 09 '13 07:01

BruceHill


People also ask

What is difference between LINQ and Lambda expression?

Language Integrated Query (LINQ) is feature of Visual Studio that gives you the capabilities yo query on the language syntax of C#, so you will get SQL kind of queries. And Lambda expression is an anonymous function and is more of a like delegate type.

What is Lambda expression in LINQ?

A lambda expression is a convenient way of defining an anonymous (unnamed) function that can be passed around as a variable or as a parameter to a method call. Many LINQ methods take a function (called a delegate) as a parameter.

What does it mean to short circuit an evaluation provide an example use case?

Short-Circuit Evaluation: Short-circuiting is a programming concept in which the compiler skips the execution or evaluation of some sub-expressions in a logical expression. The compiler stops evaluating the further sub-expressions as soon as the value of the expression is determined.

What does it mean when C# is talking about short-circuiting of logical operators?

The conditional logical OR operator || , also known as the "short-circuiting" logical OR operator, computes the logical OR of its operands. The result of x || y is true if either x or y evaluates to true . Otherwise, the result is false . If x evaluates to true , y is not evaluated.


1 Answers

The entire expression is translated to and evaluated as SQL, which means that the && operator is not short circuited as expected.

You can solve the problem by building a list or array of the ElectiveX.SubjectId that you want to search for and then use tmpList.Contains(r.Key.SubjectId) in the query. That will be translated into a WHERE IN (...) SQL expression.

like image 181
Anders Abel Avatar answered Oct 11 '22 06:10

Anders Abel