If Linq Result Is Empty - c#

If I have a linq query that looks like this, how can I check to see if there were no results found by the query?
var LinqResult =
from a in Db.Table
where a.Value0 == "ninja"
group a by a.Value1 into b
select new { Table = b};
if(LinqResult.Count() == 0) //?
{
}

You should try to avoid using the Count() method as a way to check whether a sequence is empty or not. Phil Haack has an excellent article on his blog where he discusses this antipattern.
Count() must actually enumerate all elements of the sequence - which may be expensive if the sequence is based on multiple LINQ operations (or comes from a database).
You should use the Any() extension method instead - which only attempts to see if there is at least one element in the list, but will not enumerate the entire sequence.
if( !LinqResult.Any() )
{
// your code
}
Personally, I also think that the use of Any() rather than Count() better expresses your intent, and is easier to refactor or change reliably in the future.
By the way, if what you actually want is the first (or only) member of the sequence, you should use either the First() or Single() operators instead.

if(!LinqResult.Any()) //?
{
}

Related

which of these linq queries are more performant? [duplicate]

What is the difference between these two Linq queries:
var result = ResultLists().Where( c=> c.code == "abc").FirstOrDefault();
// vs.
var result = ResultLists().FirstOrDefault( c => c.code == "abc");
Are the semantics exactly the same?
Iff sematically equal, does the predicate form of FirstOrDefault offer any theoretical or practical performance benefit over Where() plus plain FirstOrDefault()?
Either is fine.
They both run lazily - if the source list has a million items, but the tenth item matches then both will only iterate 10 items from the source.
Performance should be almost identical and any difference would be totally insignificant.
The second one. All other things being equal, the iterator in the second case can stop as soon as it finds a match, where the first one must find all that match, and then pick the first of those.
Nice discussion, all the above answers are correct.
I didn't run any performance test, whereas on the bases of my experience FirstOrDefault() sometimes faster and optimize as compare to Where().FirstOrDefault().
I recently fixed the memory overflow/performance issue ("neural-network algorithm") and fix was changing Where(x->...).FirstOrDefault() to simply FirstOrDefault(x->..).
I was ignoring the editor's recommendation to change Where(x->...).FirstOrDefault() to simply FirstOrDefault(x->..).
So I believe the correct answer to the above question is
The second option is the best approach in all cases
Where is actually a deferred execution - it means, the evaluation of an expression is delayed until its realized value is actually required. It greatly improves performance by avoiding unnecessary execution.
Where looks kind of like this, and returns a new IEnumerable
foreach (var item in enumerable)
{
if (condition)
{
yield return item;
}
}
FirstOrDefault() returns <T> and not throw any exception or return null when there is no result

How to break link between source collection and LINQ result

For example, I Have such code:
IEnumerable<RSuspectOperationCode> distinctCodes = this.Distinct(); // "this" is some collection
this.Clear()
distinctCodes.Count();
As LINQ is deferred execution query - Count gives us 0. I'm interesting - is there a approach to get a distinct collection with in-place result calculation and breaking link between source and result collection, that clearing source collection won't affect result collection?
My workaround:
List<RSuspectOperationCode> distinctCodes = new List<RSuspectOperationCode>();
distinctCodes.AddRange(this.Distinct(comparer));
this.Clear();
distinctCodes.Count();
But, I wonder, is there more elegant/shorter way?
call .ToList() whenever you want it to be executed immediately.
var distinctCodes= this.Distinct().ToList();
this.Clear();
var c1 = this.Count(); // 0
var c2 = distinctCodes.Count(); // eg. 100
Instead of calling ToList after Distinct, call it before so you have deferred execution in your distinct list:
var distinctCodes = this.ToList().Distinct();
You need to call some method that will evaluate the query. In your case, calling ToArray or ToList will do what you want by evaluating the query and placing the result in a new array or List<RSuspectOperationCode>. That new list will not be affected by any changes you make to the original list.
Note that a lot of people use ToList by default, which is wrong. Regardless of the situation, if you don't intend the change the length of a list then you should use an array rather than a collection. That means that ToArray should be your default choice and only use ToList when you specifically need a List<T>. It's not a major issue but you may as well do things the right way.
I use to add .ToList() at the end of a Linq expression to get the enumeratio done, and to have a copy of the collection.
In your case,
... = this.Distinct().ToList()
should do the trick.

C# linq possible multiple enumeration best practices

I sometimes use LINQ constructs in my C# source. I use VS 2010 with ReSharper. Now I'm getting "Possible multiple enumeration of IEnumerable" warning from ReSharper.
I would like to refactor it according to the best practices. Here's briefly what it does:
IEnumerable<String> codesMatching = from c in codes where conditions select c;
String theCode = null;
if (codesMatching.Any())
{
theCode = codesMatching.First();
}
if ((theCode == null) || (codesMatching.Count() != 1))
{
throw new Exception("Matching code either not found or is not unique.");
}
// OK - do something with theCode.
A question:
Should I first store the result of the LINQ expression in a List?
(I'm pretty sure it won't return more than a couple of rows - say 10 at the most.)
Any hints appreciated.
Thanks
Pavel
Since you want to verify if your condition is unique, you can try this (and yes, you must store the result):
var codes = (from c in codes where conditions select c).Take(2).ToArray();
if (codes.Length != 1)
{
throw new Exception("Matching code either not found or is not unique.");
}
var code = codes[0];
Yes, you need to store result as List\Array, and then use it. In that case it won't enumerate it a couple of times.
In your case if you need to be sure that there is just one item that satisfy condition, you can use Single - if there will be more than one item that satisfy conditions it will throw exception. If there will be no items at all, it also throw exception.
And your code will be easier:
string theCode = (from c in codes where conditions select c).Single();
But in that case you can't change exception text, or you need to wrap it into own try\catch block and rethrow it with custom text\exception
Finalizing enumerable with .ToList()/.ToArray() would get rid of the warning, but to understand if it is better than multiple enumerations or not would depend on codes and conditions implementations. .Any() and .First() are lazy primitives and won't execute past the first element and .Count() might not be hit at all, hence converting to a list might be more wasteful than getting a new enumerator.

Aborting a linq query after finding x items?

If I know there is only one matching item in a collection, is there any way to tell Linq about this so that it will abort the search when it finds it?
I am assuming that both of these search the full collection before returning one item?
var fred = _people.Where((p) => p.Name == "Fred").First();
var bill = _people.Where((p) => p.Name == "Bill").Take(1);
EDIT: People seem fixated on FirstOrDefault, or SingleOrDefault. These have nothing to do with my question. They simply provide a default value if the collection is empty. As I stated, I know that my collection has a single matching item.
AakashM's comment is of most interest to me. I would appear my assumption is wrong but I'm interested why.
For instance, when linq to objects is running the Where() function in my example code, how does it know that there are further operations on its return value?
Your assumption is wrong. LINQ uses deferred execution and lazy evaluation a lot. What this means is that, for example, when you call Where(), it doesn't actually iterate the collection. Only when you iterate the object it returns, will it iterate the original collection. And it will do it in a lazy manner: only as much as is necessary.
So, in your case, neither query will iterate the whole collection: both will iterate it only up to the point where they find the first element, and then stop.
Actually, the second query (with Take()) won't do even that, it will iterate the source collection only if you iterate the result.
This all applies to LINQ to objects. Other providers (LINQ to SQL and others) can behave differently, but at least the principle of deferred execution usually still holds.
I think First() will not scan the whole collection. It will return immediatelly after the first match. But I suggest to use FirstOrDefault() instead.
EDIT:
Difference between First() and FirstOrDefault() (from MSDN):
The First() method throws an exception if source contains no elements. To instead return a default value when the source sequence is empty, use the FirstOrDefault() method.
Enumerable.First
Substitue .Where( by .SingleorDefault(
This will find the first and only item for you.
But you can't do this for any given number. If you need 2 items, you'll need to get the entire collection.
However, you shouldn't worry about time. The most effort is used in opening a database connection and establishing a query. Executing the query doesn't take that much time, so there's no real reason to stop a query halfway :-)

How to avoid methods calling each other in a chain?

I have a C# class where I use a set of methods to filter out a List. I essentially do this by one method from inside the other and so on. So a( values) does some filtering, based on the output calls b(List values) or exits, b(List values) does some filtering and based on the output calls c(List values).
I want to remove this method chaining code from and control everything from the method which calls a(List values). I can use if-else-if but that will lead to too many if-else-ifs which I dont think is so great.
Are there any design patterns to solve this? Or some algo? Any help is appreciated.
Thanks.
Gaurav
What you are discribinq sounds like typical scenario to use LINQ with Iterator pattern (it can be implemented in C# easily with iterator blocks).
var results =
someCollection
.Where(c => c.SomeProperty < someValue * 2)
.Where(c => c.OtherProperty == "hi")
.OrderBy(c => c.AnotherProperty)
.Select(c => new {c.SomeProperty, c.OtherProperty});
Or as query expression:
var results = from c in SomeCollection
where c.SomeProperty < someValue * 2
where c.OtherProperty == "Hi"
orderby c.AnotherProperty
select new {c.SomeProperty, c.OtherProperty};
You can chain as many operations as you wish. Of course much more advanced operations, shuch as joins and grouping, are also available.
I recommend Jon Skeet's C# in Depth book if you really want to learn these techniques (and many others).
I want to remove this method chaining code from and control everything from the method which calls a(List values)
Well since you're filtering values you could use something like the LINQKit PredicateBuilder which would allow you to create a list of filters and apply them to the linq exprssion
However if you're doing more than just filtering you could use create instances of the Action<T> Delegate to represent actions that could be done to a your list and then apply them.
There's also the possibility of using Continuation Passing Style CPS but thinking about how that works makes my ears bleed.

Categories

Resources