简体   繁体   English

需要帮助了解MVC中的LINQ?

[英]Need help understanding LINQ in MVC?

I am quite new to MVC from webforms and it has been a really, really steep learning curve for me. 我对网络表格的MVC很新,对我来说这是一个非常非常陡峭的学习曲线。 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. 该方法是一个Action结果(没有参数)返回一个视图。 The parameters are added to tell the application to look for a "id" string. 添加参数以告诉应用程序查找“id”字符串。

I find the lambda statement a little easier to understand. 我发现lambda语句更容易理解。 The if is checking to see if the searchString is null if not it returns the movie that matches the description in searchString . if正在检查searchString是否为null,否则返回与searchString中的描述匹配的searchString

In the method however, searchString is given the value of id in the parameter. 但是,在方法中, searchString在参数中被赋予id值。 Here is where I start getting lost, right after searchString is defined, a LINQ statement is placed inside the variable movies . 这是我开始迷路的地方,在定义了searchString之后,LINQ语句放在变量movies In that statement, what is the purpose of m ? 在那个声明中, m的目的是什么? Why is it not defined or is it? 为什么没有定义或是什么? The same with the s in the lambda. 与lambda中的s相同。

Both m and s are implicitly typed. ms都是隐式输入的。 Since you are selecting m from movies , you don't need to tell LINQ what m is. 由于您是从movies中选择m ,因此您无需告诉LINQ m是什么。 It can imply the type by looking at what db.Movies is a collection of. 它可以通过查看db.Movies是什么的集合来暗示类型。 So if db.Movies was IEnumerable<Movie> (for example) then m would be a Movie . 因此,如果db.MoviesIEnumerable<Movie> (例如),那么m将是一个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. 请注意,您也隐式输入movies ,这是相同的概念。 So long as the compiler can unambiguously figure out what the type should be. 只要编译器能够明确地弄清楚类型应该是什么。

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). 变量msdb.Movies “集合”中每个Movie实例的变量(我假设这是类的调用)。

Conceptually these are similar to using and sql alias m in the following sql: 从概念上讲,这些类似于在以下sql中使用和sql别名m

select m.* from Movies m

When you later apply the where clause you're conceptually ending up with: 当您稍后应用where子句时,您在概念上最终会:

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. 请注意,这不是sql在对数据库运行时实际结束的方式,只是一种表示有助于理解。

If you look at the value of movies then you'll see that it is an IQueryable or similar. 如果你看看movies的价值,你会发现它是一个IQueryable或类似的。 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. 因此where稍后添加where子句很好 - 它只会添加到稍后运行的查询中。

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". var movies = from m in db.Movies select m粗略转换为“获取db.Movies中的所有项目并将它们暂时命名为m,然后将它们返回到IEnumerable中”。 Indeed you'll see that movies is of type IEnumerable<Movie> . 实际上你会看到movies的类型为IEnumerable<Movie>

The same goes for movies = movies.Where(s => s.Title.Contains(searchString)); 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 . :对于电影中的所有项目,暂时将它们命名为s并将Title包含searchString那些searchString作为IEnumerable

I hope it became a bit clearer. 我希望它变得更加清晰。

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...) 您正在描述处理集合'db.Movies'的方法(无论是什么......)

In descriptive language: 用描述性语言:

1) in dbo.Movies We are going to be inspecting/looping over everything everything in db.Movies. 1) in dbo.Movies我们将检查/循环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. 2) from m当我们查看它们时,1-by-1我们将把我们遇到的每个东西存储在一个名为'm'的变量中,以便在表达式中进一步使用。

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 3) select m Ok - 我们希望这个查询/表达式实际返回一些东西 - 实际上产生一些结果 - 所以,让1-by-1只返回我们之前声明的'm'

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. 变量ms使用var关键字,这意味着您不必明确提及变量的类型。 The compiler figures it out for you. 编译器会为您解决这个问题。 It's basically a variable of the IEnumerable type. 它基本上是IEnumerable类型的变量。

The var keyword is generally useful in the following when you cannot explicitly define the return type of movies as shown below- 当您无法明确定义movies的返回类型时, var关键字在以下情况下通常很有用,如下所示 -

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. 因为, new的子句是另一个未在任何地方指定的“匿名”对象,所以需要var关键字。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM