Building APIs with C# and ASP.NET Core

IQueryable & IEnumerable

Spencer Schneidenbach

Spencer Schneidenbach

Aviron Software, Microsoft MVP
Building APIs with C# and ASP.NET Core

Check out a free preview of the full Building APIs with C# and ASP.NET Core course

The "IQueryable & IEnumerable" Lesson is part of the full, Building APIs with C# and ASP.NET Core course featured in this preview video. Here's what you'd learn in this lesson:

Spencer reviews the IQueryable and IEnumerable interfaces. IEnumerable<T> is an interface representing a collection of objects that can be enumerated. It's one of the main drivers of LINQ and is used to query, filter, and manipulate collections of data. IQueryable<T> is meant to be used for querying data from a non-in-memory data source.

Preview
Close

Transcript from the "IQueryable & IEnumerable" Lesson

[00:00:00]
>> Spencer Schneidenbach: Talked about EF core. Now let's talk about actually adding it into our application. But before we do that, we need to talk about a couple of things. So if you took my last course, I talked about IEnumerable and link in great detail. But there is a construct inside of .NET that is equally as important and certainly much more important to libraries like EF Core, and it's called IQueryable.

[00:00:26]
So you'll remember that an IEnumerable is a collection of things. It's an abstraction that represents a collection of things. It could be a list of strings. It could be an array of strings, whatever the case may be. And it has a couple of properties that are important to note for this particular thing.

[00:00:42]
Remember that you can do a for each loop through each of those items, right? So for each can work on that. You'll recall as well that link can operate on IEnumerable. So all of those methods, select and where and to list, those are all extension methods that are hooked onto IEnumerable.

[00:01:02]
So copied straight from the last course is lazy evaluation. Was I lazy when I was copying as well? Maybe so but lazy evaluations is a concept that basically states that when you create a certain type of IEnumerable, like if you're using where or select, those methods are not actually.

[00:01:22]
Those methods are not actually called, those collections are not actually materialized, until you start actually trying to access objects, either by a for each loop. Or something that brings them into memory, to list or to array. So this example, numbers.where defines the query, but it doesn't actually executed immediately.

[00:01:43]
And this is a really important property like I said in my previous course, it has a lot of implications. There is one keyword that you should look up and understand as you get into your .NET journey It's called yield. And it is something that, as I mentioned in my previous course, a lot of complexity under the hood.

[00:02:02]
But it essentially creates something called a state machine that keeps track of what elements you've returned at that point. Wouldn't worry too much about it now, except to understand the implications of that thing. In addition to IEnumerable, there's a construct called IQueryable, and that's where we're going to put a lot of our focus because it is very important to EF Core.

[00:02:24]
So it's an interface that represents a collection of objects that can be queried. It is .NET standard, so it's in the Core.NET libraries. And everything inside of EF Core that you use to query databases is an IQueryable. It is similar, but different From IEnumerable in one core way.

[00:02:44]
It is used for querying data from a non in memory data source. Remember that we're talking to a database, right? We're not talking to a collection of objects in memory. If we have a billion rows in a database, it doesn't really make any sense for.NET to load all those billion rows just so it can provide link operations on them.

[00:03:01]
And that's where IQueryable comes in. Before we can dive further into IQueryable, we have to talk about these things called Expressions. Now, I could do at least a half a day course on the expression API and the implications of Expressions and what they mean and what they do.

[00:03:18]
But suffice it to say that an Expression is similar to a function definition, but not exactly the same. So these are both very valid lines of C sharp. You have your two lower method where you defined a func or a function that takes in a string, a single parameter called of string, and then returns a string.

[00:03:41]
So, you can see that here in what they call the expression body. You can see that here's our parameters, and this is our expression body, which is s.ToLower. So, s goes into s.ToLower, so it's a string, and then you call the ToLower method, and this method will. You can invoke, just like any other method, this is valid C sharp as well.

[00:04:07]
But what does it do? Well, the difference is, is that the first is a function that takes a string and returns a string, but the second is an expression which represents the data structure. It's basically a data structure that represents that function. And if you tried to, let's go ahead and attempt to do that.

[00:04:30]
In our code here, we'll just write a random test, void expression test go here. Let's copy and paste these lines of code in, again, both of these are valid C sharp. I do believe this needs to be imported and it does, okay, perfect.
>> Spencer Schneidenbach: We'll call it ToLower expression.

[00:04:54]
The difference is that if we wrote a string, like, if we had a string like. Spencer, so var name =SPENCER. We call ToLower is a function. It's just a function declared as a variable. So we can do that and you can see that it takes in a single argument.

[00:05:15]
We can pass in that name and it's going to return Spencer like that. The expression, however, is not a function, at least not yet. It's actually a data structure. So if you try to call ToLower expression, and you try to call name, compiler is gonna complain at you and say, what are you doing?

[00:05:37]
This is not a thing ToLower method, name, expression, expected 'cause it's not a method. So expressions have a lot of cool properties and I could talk about them for another hour at the very least. But it's important to know that it's data that an I Queryable can use, interpret, and then break it down into, translate it into SQL so that a database can use it.

[00:06:00]
Another fun fact about expressions is you can create them real time at runtime, and then you can compile them, and then call them like a function. So these actually can be compiled in memory, kind of a really cool thing. So it is a representation of code that is what it is, but it is not the code itself, not yet.

[00:06:20]
And I could dive more into it. But if you did want to learn more, and I'm not gonna do that now, but if you did wanna learn about it, I have a talk at this point. It's been five years since I've given that talk. I've been giving this talk for ten years, and it still gets picked up by conferences, because it's still a relevant topic.

[00:06:36]
And even this five year old talk has plenty of stuff in it, so I would recommend that. You go and watch that if you wanna learn more, but I just wanted to explain IQueryable is a construct that allows us to query a collection that does not exist in memory.

[00:06:51]
And that expression trees are kinda the conduit with which we express to the IQueryable what it is we want and how we get it.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now