2015-04-23 5 views
8

Я довольно новичок в MVC из webforms, и это была действительно крутая кривая обучения для меня. Вот эта функция в следующем учебном пособии:Нужна помощь в понимании LINQ в MVC?

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); 
} 

Вот что я думаю, что знаю, что это происходит. Этот метод является результатом действия (без параметров), возвращающим представление. Параметры добавляются, чтобы указать приложению искать строку «id».

Я нахожу заявление лямбда немного легче понять. if проверяет, имеет ли значение searchString значение null, если оно не возвращает фильм, соответствующий описанию в searchString.

В способе, однако, в параметре searchString задано значение id. Здесь я начинаю заблуждаться, сразу после определения searchString оператор LINQ помещается внутри переменной movies. В этом заявлении, какова цель m? Почему это не определено или не так ли? То же самое с s в лямбда.

+0

Я считаю, что это эквивалентно 'var movies = db.Movies.Select (m => m)', который (по логике, по крайней мере) не-op (но это зависит от поставщика LINQ, я бы догадался). В основном, все это говорит: «Выберите все фильмы, если нет строки поиска, и в этом случае сохраняйте только фильмы, содержащие эту строку поиска». –

+0

@ TheodorosChatzigiannakis, что я понимаю из вашего комментария. Выберите из фильма, где m больше или равно m .... im guessing m также частично определяется поисковой строкой. верный? Что вы подразумеваете под no-op? – Skullomania

+0

@ TheodorosChatzigiannakis это настройка для получения правильного типа для 'var'. 'db.Movies', скорее всего, является' DbSet <> ', который не позволяет добавлять туда. – Johnbot

ответ

5

И неявно введены как m, так и s. Поскольку вы выбираете m от movies, вам не нужно указывать LINQ, что такое m. Это может означать тип, глядя на то, что db.Movies - это коллекция. Так, если db.Movies был IEnumerable<Movie> (например), то m будет Movie.

Там нет ничего, чтобы остановить вас от указания типа, если вы действительно хотите, чтобы вы могли ввести:

var movies = from Movie m in db.Movies 
      select m; 

Но вы редко нужно.

Обратите внимание, что вы также неявно печатаете movies, это та же концепция. Пока компилятор может однозначно определить, какой тип должен быть.

1

var movies = from m in db.Movies select m примерно переводится как «Возьмите все элементы в db.Movies и назовите их временно m, а затем верните их в IEnumerable». Действительно, вы увидите, что movies имеет тип IEnumerable<Movie>.

То же самое касается movies = movies.Where(s => s.Title.Contains(searchString));: Для всех элементов в фильмах, назвать их временно s и вернуть тех, чьи Title содержит ваш searchString как IEnumerable.

Надеюсь, это стало немного понятнее.

4

Переменные m и s переменные для каждого экземпляра Movie в рамках «коллекции» db.Movies (я предполагаю, что это то, что называется классом).

Концептуально это похоже на использование и SQL псевдоним m в следующем SQL:

select m.* from Movies m 

Когда вы примените этот where пункт вы концептуально заканчиваясь с:

select * from (
    select m.* from Movies m 
) s 
where s.Title like '%' + searchString + '%' 

Обратите внимание, что это не то, как sql на самом деле заканчивается, когда он работает с базой данных, а просто представляет собой представление для понимания.

Если вы посмотрите на значение movies, вы увидите, что это IQueryable или аналогичный. Это означает, что он пока еще не выполнен - ​​вы ничего не вернули. Поэтому добавление предложения where в порядке - оно просто добавляется к запросу, который будет запущен позже.

1

Ok - Я постараюсь объяснить, что происходит:

с:

var movies = from m in db.Movies select m; 

Вы описываете способ обработки коллекции 'db.Movies' (что бы это ни ...)

в описательном языке:

1) in dbo.Movies Мы собираемся быть инспектирование/зацикливания над всем и все в db.Movies.

2) from m По мере прохождения по ним 1-на-1 мы будем хранить каждую вещь, с которой мы сталкиваемся, в переменной, называемой «m», для дальнейшего использования в выражении.

3) select m Ok - мы хотим, чтобы этот запрос/выражение на самом деле вернуть что-то - на самом деле дают некоторые результаты - так, позволяет 1-на-1 просто возвращает «т» мы объявленную ранее

0

Переменные m и s используют ключевые слова var, что означает, что вам не нужно явно указывать тип переменной. Компилятор подсчитал это для вас. Это в основном переменная типа IEnumerable.

var ключевое слово, как правило, полезно в дальнейшем, когда вы не можете явно указать тип возвращаемого movies, как как указано ниже

var movies = from m in db.Movies 
      select new { m.Attr1, m.Attr2 } ; 

Так, положение в new еще один «анонимные» объект нигде не указано, вам нужно ключевое слово var.

Смежные вопросы