Good question. As Reed points out, they all mostly stem from
deferred execution (but unlike him, I consider this a drawback). Just thinking why deferred executions are not performed by remembering the state). Here are a few examples - all these are more or less variants of the problem of delayed execution.
1) I'm too lazy to do something on time
Linq is available on demand only.
The common mistake is newbies (I included in the past) make does not know about deferred execution. For example, something like
var p = listOfAMillionComplexItems.OrderBy(x => x.ComplexProperty);
works in an instant, but the actual sorting does not end until you list the list, in other words, the execution will not be completed until you need the result of the execution. To execute it, you need something like:
foreach(var item in p)...
See them as SQL queries. if you have
var query = from i in otherValues where i > 5 select i;
consider it akin to writing
string query = "SELECT i FROM otherValues WHERE i > 5";
Does the last call to db? Not. You should
Execute(query);
This is the same with Linq.
2) I live in the present
Be careful when changing variables inside Linq expressions later.
To be safe, first create backup variables, and then use a backup in the query if the variable may change later before the query actually executes.
From here:
decimal minimumBalance = 500; var customersOver500 = from c in customers where c.Balance > minimumBalance select c; minimumBalance = 200; var customersOver200 = from c in customers where c.Balance > minimumBalance select c; int count1 = customersOver500.Count(); int count2 = customersOver200.Count();
Suppose we have four clients with the following balances: 100, 300, 400 and 600. What will count1 and count2 be? They will be equal to 3. "customerOver500" refers to the variable "minimumBalance", but the value is not obtained until the query results are repeated (through the for / each loop, ToList () or even "Count (), as shown above) At the time when the value is used to process the request, the value for minimumBalance has already changed to 200, so both LINQ queries give the same results (clients with a balance of more than 200).
3) My memory is too weak to remember the values โโof the past
Same as above, context is slightly different.
or is it from the same site:
Consider this simple example method using LINQ-to-SQL to get a list of clients:
public IEnumerable<Customer> GetCustomers() { using(var context = new DBContext()) { return from c in context.Customers where c.Balance > 2000 select c; } }
It seems pretty harmless - until you get an "ObjectDisposedException" when trying and listing the collection. What for? Because LINQ does not actually execute the query until you try and list the results. The DBContext class (which provides the Customers collection) is deleted when this call completes. After you try and list through the collection, it refers to the DBContext.Customers class and you get an exception.
4) Don't try to catch me, I can still slip away
Try-catch is meaningless for statement if it is not reasonable to use it.
Instead, it will work better with exception handling.
try { wallet = bank.Select(c => Convert.ToInt32("")); } catch (Exception ex) { MessageBox.Show("Cannot convert bad int"); return; } foreach(int i in wallet)
We also do not receive the correct error message, and the function does not close return .
5) I am not only unloving, but also not involved in mistakes
Linq is executed every time you list them. Therefore, do not reuse Linq enumerations.
Suppose you have an IQueryable or IEnumerable expression returned from a Linq expression. Now enumerating the collection will execute the statement, but only once? No, every time you do it. It has bitten me in the past. If you have:
var p = listOfAMillionComplexItems.OrderBy(x => x.ComplexProperty); MessageBox.Show(p.Count().ToString());
So do it better
int i = p.Count(); //store in a variable to access count //or better var list = p.ToList(); //and start using list
6) If you do not know how to use me, I can cause side effects!
The same as above just shows how reusing Linq enumerations can lead to unwanted behavior.
Make sure you are not performing side effects (since re-enumeration in Linq is much more common). To give a wild example,
p = bag.Select((t, i) => {if(i == 1) MessageBox.Show("Started off"); return t;});
If you list twice, you know that an unwanted thing may happen.
7) Be careful with the order I am doing when chaining
Not only for variables, even chained Linq functions can execute in a different order from what you usually expect (although the behavior is correct). Do not think about the need (step by step), think about how Linq can fulfill it.
For example,
var d = Enumerable.Range(1, 100); var f = d.Select(t => new Person()); f = f.Concat(f); f.Distinct().Count() ??
What will be the number of individuals in f ? I think 100, no, but it's 200. The problem is that when the actual execution of the concatenation logic is executed, f is still d.Select(t => new Person() not executed . Thus, this effectively gives in
f = d.Select(t => new Person()).Concat(d.Select(t => new Person()));
which then has 200 different members. Here is a link to the actual problem
8) Hey, we are actually smarter than you think.
Not a reservation in itself, but there are many cases where Linq can surpass your real style program. Therefore, before optimization, give a second thought and even a guideline.
The reason that delayed execution is mostly done on demand makes Linq much more efficient than it seems. The iterator block "gives" one element at a time as required, providing the ability to stop execution when it is no longer needed. Here is a very good question that describes this in detail: Does the order of LINQ extension methods not affect performance?
9) I did not want a number crunch
Overuse of Linq can make code inefficient as well as less readable.
Linq is not the right tool for number crunching algorithms, especially for large datasets whose complexity can scale exponentially. Sometimes only two cycles would be better. The same can be applied to raw SQL compared to LINQ to SQL.
10) Hire me for the right job
Asking Linq to keep in mind your regular business is a poor choice of software that runs counter to readability.
Some for example:
medicines.Any(p => { Console.WriteLine(p); return false; });
to intercept on an enumerable.
or
medicines = medicines.Select(p => { p.Id = 3; return p; });
Just bad tools.
11) Debugging and profiling can be a nightmare
It's hard to keep track of what's happening under the hood, the Linq expression from VS
Not that it was completely impossible, but its task bit debugged the linq query as efficiently as non-linq code from VS itself. Profiling also gets a little more complicated due to the nature of deferred execution. But this should not stop anyone from doing the trivial one or two liners!
A bunch of reservations related to deferred execution more or less! This question is here . Some related readings on SO:
Examples when not to use LINQ
Pros and cons of LINQ (language integral query)
What is the biggest mistake people make when using LINQ?
disadvantages of linq