Reputation: 2215
I am quite new to MVC from webforms and it has been a really, really steep learning curve for me. Here is the function in the tutorial that I am following:
public ActionResult Index(string id)
{
string searchString = id;
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies);
}
Here is what I think I know that is happening. The method being an Action result(without parameters) re returning a view. The parameters are added to tell the application to look for a "id" string.
I find the lambda statement a little easier to understand. The if
is checking to see if the searchString
is null if not it returns the movie that matches the description in searchString
.
In the method however, searchString
is given the value of id
in the parameter. Here is where I start getting lost, right after searchString
is defined, a LINQ statement is placed inside the variable movies
. In that statement, what is the purpose of m
? Why is it not defined or is it? The same with the s
in the lambda.
Upvotes: 8
Views: 1944
Reputation: 41539
The variables m
and s
are variables for each instance of Movie
within the db.Movies
"collection" (I assume that's what the class is called).
Conceptually these are similar to using and sql alias m
in the following sql:
select m.* from Movies m
When you later apply the where
clause you're conceptually ending up with:
select * from (
select m.* from Movies m
) s
where s.Title like '%' + searchString + '%'
NOTE that this isn't how the sql actually ends up when it runs against the database, just a representation to aid understanding.
If you look at the value of movies
then you'll see that it is an IQueryable
or similar. This means that it hasn't actually executed yet - you've not returned anything. So adding the where
clause later is fine - it just gets added to the query that'll get run later.
Upvotes: 4
Reputation: 918
The variables m
and s
are using the var
keywords which means that you don't have to explicitly mention the type of the variable. The compiler figures it out for you. It's basically a variable of the IEnumerable
type.
The var
keyword is generally useful in the following when you cannot explicitly define the return type of movies
as shown below-
var movies = from m in db.Movies
select new { m.Attr1, m.Attr2 } ;
Since, the clause within new
is another 'anonymous' object not specified anywhere, you need the var
keyword.
Upvotes: 0
Reputation: 19646
Ok - I'll try to explain what's happening:
with:
var movies = from m in db.Movies select m;
You are describing a way of processing the collection 'db.Movies' (whatever that is...)
In descriptive language:
1) in dbo.Movies
We are going to be inspecting/looping over everything everything in db.Movies.
2) from m
As we go over them, 1-by-1 we'll store each thing we come across in a variable called 'm' for further use in the expression.
3) select m
Ok - we want this query / expression to actually return something - to actually yield some results - so, lets 1-by-1 just return the 'm' we declared earlier
Upvotes: 1
Reputation: 3580
var movies = from m in db.Movies select m
roughly translates to "Take all items in db.Movies and name them temporarily m, then return them in an IEnumerable". Indeed you'll see that movies
is of type IEnumerable<Movie>
.
The same goes for movies = movies.Where(s => s.Title.Contains(searchString));
: For all items in movies, name them temporarily s
and return those whose Title
contains your searchString
as an IEnumerable
.
I hope it became a bit clearer.
Upvotes: 2
Reputation: 45135
Both m
and s
are implicitly typed. Since you are selecting m
from movies
, you don't need to tell LINQ what m
is. It can imply the type by looking at what db.Movies
is a collection of. So if db.Movies
was IEnumerable<Movie>
(for example) then m
would be a Movie
.
There is nothing to stop you from specifying the type if you really want to, so you could type:
var movies = from Movie m in db.Movies
select m;
But you rarely need to.
Note you are also implicitly typing movies
, it's the same concept. So long as the compiler can unambiguously figure out what the type should be.
Upvotes: 5