A LINQ query returns what type of data?

Asked

Viewed 375 times

10

I searched about the type of data that is returned when we run a query on LINQ, but I was unsuccessful.

I would like to know what kind of data is returned by a query using the LINQ, if it is a generic object or an object of the class type that represents my table in the database?

Let us consider this example to illustrate the situation:

var query = from p in database.Pessoa select p;

In the above example, what is the type of data that would be assumed by the variable query?

  • Have you tried compiling and see which type is inferred by the compiler?

2 answers

9


It’s gotta be a guy IEnumerable (which is not a concrete type). Nothing prevents returning other types that are suitable to the methods normally used in LINQ, provided that it implements the same as a IEnumerable implements. That is, it can return any type that implements the method GetEnumerator(). Because LINQ is just a way to take data that can be enumerated.

Another very common interface to be used in LINQ is the IQueryable who inherits from IEnumarable, as can be seen in the documentation. This is the case for the expression used in the question. Anything can be returned, as long as it is IEnumerable.

How the LINQ works

The most important thing is that people imagine that it returns a concrete data, a list of data that you can see in memory all of them right after performing this expression. That’s not what actually happens.

If you perform a perforation or some specific performance accompaniment in this expression you will see that it is too fast. Moreover, it has complexity essentially O(1). No matter the size of the data that has to handle it always runs at the same time (it varies only according to the complexity of the expression, not the data). It’s usually only a few milliseconds, or less.

LINQ is a technology makes lazy assessment. It avails itself of generators, are written with yield. That’s why you need a GetEnumerator(), the yield is based on an enumeration.

In fact you only access the data you really need at the time you use it. One of these ways is to call a ToList(), ToArray() or another that requires concrete data. At that moment the expression is actually applied to the original collection and generates another collection. You can measure that, it’s usually very slow in cases of large collections that need to be evaluated. Luckily some expressions don’t have to go all the way to find out what you expected.

It is often a mistake to do this. Many programmers do because they have learned that at the end of a LINQ expression they should put these methods. Yes, in many cases you should, but not always. When this is done, the expression is applied to all items in the collection that you need to evaluate. There are cases where you do not want to make this consequence. There are cases you even want, but you can make a loop along with the evaluation of the items. When applying one of these methods that concretizes the collection evaluated by LINQ and then runs a loop, are two loops occurring, this can be resource waste.

Some programmers think LINQ is a magical thing. Others even think, but it should be inefficient to do all this stuff. Because if you have a method that loops all the items, then you have another method that loops all the items, and you can have a whole plethora of methods, each with a loop, it should be very slow to do all this.

If you’re curious to see the source of one of these methods (no . NET Core) has a bond in each. But the yield is the secret. In fact it only executes one step of the loop and closes. That is, it applies the necessary predicate in the item and goes to the next method that applies its part and delivery to the next. Only after all methods run on an item does it go to the next item in the collection. So in practice only one loop is executed no matter how many LINQ methods are invoked in that expression (this may be a little more complicated than that in some cases, but let’s not make the explanation more precise).

Inefficiency

Of course the yield it has its cost. If you do it in hand in a single loop by putting together everything you need, it will surely be faster. In some cases the performance loss can be pretty bad. In a database can be insignificant.

Some people say that the LINQ’s performance loss is negligible. It’s not like that. There are cases where you go from a few microseconds without LINQ to milliseconds when you use it. It can be thousands of times more. And then one says it will still be well below a second. But if you put this in a larger loop with thousands of runs, it’s the difference between running the whole in milliseconds or in several minutes.

Completion

So don’t think that variable (query in the specific case) it has some data in it right away. Ali has an object with the expression (somewhat roughly the code needed to execute the expression) to be executed, and not the data.

In a IQueryable (see the difference) will probably have a how to access an SQL expression (not that precise) already mounted during the compilation of the runtime expression. The apparently great time of this expression that evaluates no given is precisely by this compilation.

When executing a method that materializes the expression the return will be a concrete type that is necessary. In this specific case it will be a List<Pessoa> (probably, but it depends, it can be another collection).

7

In the above example, what is the type of data that would be assumed by the variable query?

An object that implements IQueryable<T>, being T the guy Pessoa.

IQueryable is not an enumeration. It is an object that builds filters that will be used to compose an enumeration in memory.

Considering LINQ to Entities or Entity Framework, the idea here is to build an SQL based on the predicate written and, when solving the object for an enumeration (IEnumerable), SQL is executed by the data provider and the return transformed into an enumeration.

If it were an operation in memory, LINQ would build an object that works as an enumeration filter, returning another enumeration with filtered results in resolution to IEnumerable.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.