Clean way to check for Null in Lambda Expressions - c#

I have seen a lot of questions on this but was not able to find a clean solution:
I have the following lambda expression:
var result = Store.FirstOrDefault(x.Products.Coupon[0] == 100);
I would like to check for null for the Coupon collection to check to see if its not null and then compare the first coupon with the value 100. What would be a clean way to check for NULL for Coupon in the lambda? I do not want to use an extension method to check for null. I would like to do the check inline.

var result = Store.FirstOrDefault(x => x.Products.Coupon != null && x.Products.Coupon.Any() && x.Products.Coupon[0] == 100);

Related

Any alternative for this 'Where' LINQ query

i have this linq query. I need to look for any good alternative if possible for this higlighted lambda expression inside Where condition. I was thinking to use coalesce condition ( ?? ) but couldnt make a query.
.Where(p => p.Property== null ? true : p.Property.SubPropertyList.Contains(Item))
So, I want to get those items from list which has a property null or if not null then satisfies a condition ( Contains() )
You need to create a predicate.
A function that will return true of false.
In you case:
.Where(***p => p.PalletMission == null || p.PalletMission.Destinations.Contains(currentGtpOrder.GtpStation.Node))
var result = list
.Where(p =>p.Property == null || p.Property?.SubPropertyList.Contains(1) == true);

Null Propagation

When the linq query condition is not met, I'd expect a null to be returned from questions.FirstOrDefault() - but instead, an exception
Sequence contains no matching element
is thrown. Any ideas why?
var firstQ = questions.FirstOrDefault(a =>
a.Answers.Single(x => x.CourseAssignmentId ==
courseAssignmentId)?.Score == null) ?? questions.FirstOrDefault();
That's the difference between Single and SingleOrDefault.
Single throws an exception if there's any number of items different than 1 that match your predicate.
You should be using FirstOrDefault() instead. BTW you can combine the condition probably like
a.Answers.Single(x => x.CourseAssignmentId == courseAssignmentId && x.Score == null)
As others have already mentioned, it's the expected behavior of Enumerable.Single.
Anyway, it looks like an XY problem. Probably you should store the last scored question somewhere (e.g a dictionary).
That is, you could refactor your code as follows:
var assignmentScoredQuestionMap = new Dictionary<int, Question>();
// Fill the whole dictionary:
// You need to add for which assignment identifier you've answered a question
int assignmentId = 384;
// If the whole assignment exists, you set lastScoredQuestion, otherwise
// you set it to first question.
if(!assignmentScoredQuestionMap.TryGetValue(assignmentId, out var lastScoredQuestion))
lastScoredQuestion = questions.FirstOrDefault();

Check if query to DB is empty

The action method in the controller receive a value, like a couple of letters. The code checks if the table contains any of this letters. I'm using this code for that task:
var result = db.People.Where(b => b.Name.ToUpper().Contains(filter.ToUpper()));
But how can I check if the result variable is empty or null, when there are not any matching letters? I tested this, but it's not working!
If(result == ""){
// Do something
}
I would like to use Viewbag to send a message that there was no match or perhaps do this check in the View. I'm using this with some AJAX and Partial Views and it's working perfect, but I just want show a message if there are not any matches. What is the best way to check if the result value is empty or null?
The simplest way would be by using !result.Any():
var result = db.People.Where(b => b.Name.ToUpper().Contains(filter.ToUpper()));
If(!result.Any()){
// Do something
}
From MSDN on IEnumerable:
Any()
Determines whether a sequence contains any elements.
Fits exactly what you need.
Try this, Using FirstOrDefault it will give you the first record from the result, else if no result is yielded from the query it returns default value that is null,
var result = db.People.Where(b => b.Name.ToUpper().Contains(filter.ToUpper())).FirstOrDefault();
If(result == null){
// Do something
}
Or if you want to use this result, to manipulate something in your code then you can use the ToList(). It will return you list of values and if the query didnt yield anything then the list count will be 0.
var result = db.People.Where(b => b.Name.ToUpper().Contains(filter.ToUpper())).ToList();
If(result.Count == 0){
// Do something
}
Your code is not working because the code is returning an object not a string if you want to return a string then you have to use the "Select" clause to select a specific field and if you want to check in the same code then modify :
var result = db.People.Where(b => b.Name.ToUpper().Contains(filter.ToUpper())).ToList();
if(result != null && result.Count > 0)
it will work for you.
For IEnumerable we can use Any(), your code will can be written as
if(!db.People.Where(b => b.Name.ToUpper().Contains(filter.ToUpper())).Any() {
// do some thing
}

How to check if array is not null in LINQ?

I Have this where statement in LINQ:
(users != null && users.Contains(x.Appointment.UserId))
users is an int[]. When i run this code i have an exception:
Unable to create a null constant value of type 'System.Int32[]'. Only
entity types, enumeration types or primitive types are supported in
this context.
What should i do?
I had a similar problem. Assuming you are starting with something like this:
var filtered = appointments
.Where(x => users != null && users.Contains(x.Appointment.UserId));
As #CarstenKönig suggests, try moving the null check outside of the Where clause:
var filtered = users != null ?
appointments.Where(x => users.Contains(x.Appointment.UserId)) :
appointments;
That means the null check is handled by C#, and LINQ to Entities doesn't attempt to convert it to SQL.
As others suggested you could move bool check outside the closure and use resulting bool in your Where statement:
var usersNotNull = users != null;
var users = users == null ? new string[0] : users;
query.Where(x => usersNotNull && users.Contains(x.Appointment.UserId));

String.IsNullOrEmpty in LINQ To SQL query?

My DBML exposes a record set that has a nullable nvarchar field. This nullable nvarchar field is represented as a string in my C# code.
Sometimes this field is null, sometimes it is an empty string, and sometimes it actually has a value.
Does String.IsNullOrEmpty() work in LINQ To SQL? For instance, would the following work:
var results = from result in context.Records
where String.IsNullOrEmpty(result.Info) == false
select result;
Curiously, per MSDN String.IsNullOrEmpty is supported (by virtue of it not being unsupported), yet I can only find complaints about it not being supported.
However, if it does work you should not explicitly compare it to a boolean value, instead:
var results = from result in context.Records
/*XXX broke :( where !String.IsNullOrEmpty(result.Info) */
where !(result.Info == null || result.Info.Equals(""))
select result;
I don't know if that works, but I'm sure this does:
where (result.Info ?? "") != ""
(strongly recommend the parens, query generator can get confused without them)
It is not supported since attempting to use it results in a NotSupportedException being thrown with this message:
Method 'Boolean IsNullOrEmpty(System.String)' has no supported
translation to SQL.
Instead, you can use this approach to do the same thing:
var results = from result in context.Records
where result.Info != null && result.Info.Length > 0
select result;
You may also use result.Info != String.Empty instead of checking the length. Both approaches will work.
I had problems with all answers except for #ahmad-mageed's answer.
Ended up using a more concise syntax of:
where (result.Info ?? "").Length > 0
Or
result => (result.Info ?? "").Length > 0
You can use a function as argument to the Where method if you use a Linq query, e.g.
var results = context.Records.Where(string.IsNullOrEmpty);
But in this case that would give you all null or empty elements, instead of the opposite. Then create an extension method to the string class (e.g. string.IsNotNullOrEmpty) or do something like this:
var results = context.Records.Except(context.Records.Where(string.IsNullOrEmpty));

Categories