Создание классов модели в LINQ to SQL (VB)Creating Model Classes with LINQ to SQL (VB)

корпорацией Майкрософтby Microsoft

Скачать PDFDownload PDF

Цель этого учебника состоит в том, чтобы объяснить один метод создания типов моделей для ASP.NET mVC-приложении.The goal of this tutorial is to explain one method of creating model classes for an ASP.NET MVC application. В этом уроке вы узнаете, как создавать классы моделей и выполнять доступ к базе данных, пользуясь преимуществами Microsoft LIN' для S'L.In this tutorial, you learn how to build model classes and perform database access by taking advantage of Microsoft LINQ to SQL.

Цель этого учебника состоит в том, чтобы объяснить один метод создания типов моделей для ASP.NET mVC-приложении.The goal of this tutorial is to explain one method of creating model classes for an ASP.NET MVC application. В этом уроке вы узнаете, как создавать классы моделей и выполнять доступ к базе данных, пользуясь преимуществами Microsoft LIN' для S'L.In this tutorial, you learn how to build model classes and perform database access by taking advantage of Microsoft LINQ to SQL.

В этом учебнике мы создаем базовое приложение базы данных Movie.In this tutorial, we build a basic Movie database application. Мы начинаем с создания приложения базы данных Movie самым быстрым и простым способом.We start by creating the Movie database application in the fastest and easiest way possible. Мы выполняем весь наш доступ к данным непосредственно от наших действий контроллера.We perform all of our data access directly from our controller actions.

Далее вы узнаете, как использовать шаблон репозитория.Next, you learn how to use the Repository pattern. Использование шаблона репозитория требует немного больше работы.Using the Repository pattern requires a little more work. Однако преимущество множества этого шаблона заключается в том, что он позволяет создавать приложения, которые адаптируются к изменениям и могут быть легко протестированы.However, the advantage of adopting this pattern is that it enables you to build applications that are adaptable to change and can be easily tested.

Что такое модельный класс?What is a Model Class?

Модель MVC содержит всю логику приложения, которая не содержится в представлении MVC или контроллере MVC.An MVC model contains all of the application logic that is not contained in an MVC view or MVC controller. В частности, модель MVC содержит все ваши бизнес-приложения и логику доступа к данным.In particular, an MVC model contains all of your application business and data access logic.

Вы можете использовать различные технологии для реализации логики доступа к данным.You can use a variety of different technologies to implement your data access logic. Например, можно создать классы доступа к данным с помощью рамочных рамок Сущности Майкрософт, NHibernate, Subsonic или ADO.NET классов.For example, you can build your data access classes using the Microsoft Entity Framework, NHibernate, Subsonic, or ADO.NET classes.

В этом учебнике я использую LIN'l для запроса и обновления базы данных.In this tutorial, I use LINQ to SQL to query and update the database. Компания «ЛИНЗ» и «СЗЛ» предоставляет вам очень простой метод взаимодействия с базой данных Microsoft S'L Server.LINQ to SQL provides you with a very easy method of interacting with a Microsoft SQL Server database. Тем не менее, важно понимать, что ASP.NET платформа MVC никоим образом не привязана к LIN-образу и S'L.However, it is important to understand that the ASP.NET MVC framework is not tied to LINQ to SQL in any way. ASP.NET MVC совместим с любой технологией доступа к данным.ASP.NET MVC is compatible with any data access technology.

Создание базы данных фильмовCreate a Movie Database

В этом уроке , чтобы проиллюстрировать, как можно создавать классы моделей, мы создаем простое приложение базы данных Movie.In this tutorial -- in order to illustrate how you can build model classes -- we build a simple Movie database application. Первым шагом является создание новой базы данных.The first step is to create a new database. Нажмите правой_кнопкой папку App Data в окне Solution Explorer и выберите опцию меню Добавить, Новый пункт.Right-click the App_Data folder in the Solution Explorer window and select the menu option Add, New Item. Выберите шаблон базы данных сервера S'L Server, назовите его именем MoviesDB.mdf и нажмите кнопку Добавить (см. рисунок 1).Select the SQL Server Database template, give it the name MoviesDB.mdf, and click the Add button (see Figure 1).

Добавление новой базы данных серверов S'LAdding a new SQL Server Database

Рисунок 01: Добавление новой базы данных серверов S'L(Нажмите, чтобы просмотреть полноразмерное изображение)Figure 01: Adding a new SQL Server Database (Click to view full-size image)

После создания новой базы данных можно открыть базу данных, дважды нажав_файл MoviesDB.mdf в папке App Data.After you create the new database, you can open the database by double-clicking the MoviesDB.mdf file in the App_Data folder. Двойное нажатие файла MoviesDB.mdf открывает окно Server Explorer (см. рисунок 2).Double-clicking the MoviesDB.mdf file opens the Server Explorer window (see Figure 2).

Окно Server Explorer называется окном Database Explorer при использовании визуального веб-разработчика.The Server Explorer window is called the Database Explorer window when using Visual Web Developer.

Использование окна Server ExplorerUsing the Server Explorer window

Рисунок 02: Использование окна Server Explorer(Нажмите, чтобы просмотреть полноразмерное изображение)Figure 02: Using the Server Explorer window (Click to view full-size image)

Нам нужно добавить одну таблицу в нашу базу данных, которая представляет наши фильмы.We need to add one table to our database that represents our movies. Нажмите правой кнопкой папку Таблицы и выберите вариант меню Добавить новый стол.Right-click the Tables folder and select the menu option Add New Table. Выбор этой опции меню открывает конструктор таблицы (см. рисунок 3).Selecting this menu option opens the Table Designer (see Figure 3).

Использование окна Server ExplorerUsing the Server Explorer window

Рисунок 03: Таблица Дизайнер (Нажмите, чтобы посмотреть полноразмерное изображение)Figure 03: The Table Designer (Click to view full-size image)

Нам нужно добавить следующие столбцы в таблицу базы данных:We need to add the following columns to our database table:

Имя столбцаColumn Name Тип данныхData Type Разрешить значения NULLAllow Nulls
ИдентификаторId IntInt FalseFalse
TitleTitle Нварчар (200)Nvarchar(200) FalseFalse
ДиректорDirector Нварчар (50)Nvarchar(50) FalseFalse

Вы должны сделать две специальные вещи для колонки Id.You need to do two special things to the Id column. Во-первых, необходимо отметить столбец Id в качестве основного ключевого столбца, выбрав столбец в таблице Designer и нажав значок ключа.First, you need to mark the Id column as a primary key column by selecting the column in the Table Designer and clicking the icon of a key. При выполнении вставок или обновлений в базе данных необходимо указать основные ключевые столбцы.LINQ to SQL requires you to specify your primary key columns when performing inserts or updates against the database.

Далее необходимо пометить столбец Id в качестве столбца identity, назначив значение «Да» свойству Is Identity (см. рисунок 3).Next, you need to mark the Id column as an Identity column by assigning the value Yes to the Is Identity property (see Figure 3). Столбец идентификации — это столбец, который автоматически присваивается новому номеру при добавлении новой строки данных в таблицу.An Identity column is a column that is assigned a new number automatically whenever you add a new row of data to a table.

После внесения этих изменений сохраните таблицу с именем tblMovie.After you make these changes, save the table with the name tblMovie. Вы можете сохранить таблицу, нажав кнопку Сохранить.You can save the table by clicking the Save button.

Создание LIN-класса для классов S'LCreate LINQ to SQL Classes

Наша модель MVC будет содержать классы LIN' to S'L, представляющие таблицу базы данных tblMovie.Our MVC model will contain LINQ to SQL classes that represent the tblMovie database table. Самый простой способ создать эти классы LIN' в S'L — это нажать правой кнопкой кнопку «Модели», выберите Добавить, новый пункт, выберите шаблон LIN' для s'L Classes, дать классам название Movie.dbml и нажать кнопку «Добавить» (см. рисунок 4).The easiest way to create these LINQ to SQL classes is to right-click the Models folder, select Add, New Item, select the LINQ to SQL Classes template, give the classes the name Movie.dbml, and click the Add button (see Figure 4).

Создание классов LIN-in s-LCreating LINQ to SQL classes

Рисунок 04: Создание LIN-класса для классов S'L(Нажмите, чтобы просмотреть полноразмерное изображение)Figure 04: Creating LINQ to SQL classes (Click to view full-size image)

Сразу же после создания фильма LIN' для классов S'L появляется объектреляальный конструктор.Immediately after you create the Movie LINQ to SQL Classes, the Object Relational Designer appears. Можно перетащить таблицы баз данных из окна Server Explorer в объектный реляционный конструктор для создания классов LIN'а в S-L, представляющих определенные таблицы баз данных.You can drag database tables from the Server Explorer window onto the Object Relational Designer to create LINQ to SQL Classes that represent particular database tables. Нам нужно добавить таблицу базы данных tblMovie на объектрелую реляционную конструктор (см. рисунок 4).We need to add the tblMovie database table onto the Object Relational Designer (see Figure 4).

Использование объектного реляционный конструкторUsing the Object Relational Designer

Рисунок 05: Использование объекта реляционный конструктор (Нажмите, чтобы посмотреть полноразмерное изображение)Figure 05: Using the Object Relational Designer (Click to view full-size image)

По умолчанию объектреляритный конструктор создает класс с тем же именем, что и таблица базы данных, которую вы перетаскиваете на конструктора.By default, the Object Relational Designer creates a class with the very same name as the database table that you drag onto the Designer. Тем не менее, мы не хотим называть наш класс tblMovie.However, we don't want to call our class tblMovie. Таким образом, нажмите на имя класса в Designer и изменить название класса на фильм.Therefore, click the name of the class in the Designer and change the name of the class to Movie.

Наконец, не забудьте нажать кнопку «Сохранить» (изображение дискеты), чтобы сохранить LIN-классы для S'L.Finally, remember to click the Save button (the picture of the floppy) to save the LINQ to SQL Classes. В противном случае классы LIN's to S'L не будут сгенерированы проектировщиком отношений объектов.Otherwise, the LINQ to SQL Classes won't be generated by the Object Relational Designer.

Использование ЛИНЗ для СЗЛ в действии контроллераUsing LINQ to SQL in a Controller Action

Теперь, когда у нас есть классы LIN's to S'L, мы можем использовать эти классы для извлечения данных из базы данных.Now that we have our LINQ to SQL classes, we can use these classes to retrieve data from the database. В этом разделе вы узнаете, как использовать lin'l для классов S'L непосредственно в рамках действия контроллера.In this section, you learn how to use LINQ to SQL classes directly within a controller action. Мы подемонстрируем список фильмов из таблицы данных tblMovies в представлении MVC.We'll display the list of movies from the tblMovies database table in an MVC view.

Во-первых, нам нужно изменить класс HomeController.First, we need to modify the HomeController class. Этот класс можно найти в папке контроллеров вашего приложения.This class can be found in the Controllers folder of your application. Изменение класса, чтобы он выглядел как класс в листинге 1.Modify the class so it looks like the class in Listing 1.

Список 1 -Controllers\HomeController.vbListing 1 – Controllers\HomeController.vb

<HandleError()> _
Public Class HomeController

     Inherits System.Web.Mvc.Controller

     Function Index()
          Dim dataContext As New MovieDataContext()
          Dim movies = From m In dataContext.Movies _
               Select m
          return View(movies)
     End Function
End Class

В действии Индекса () в листинге 1 используется класс LIN' to S'L DataContext (MovieDataContext) для представления базы данных MoviesDB.The Index() action in Listing 1 uses a LINQ to SQL DataContext class (the MovieDataContext) to represent the MoviesDB database. Класс MoveDataContext был создан проектировщиком объектов Visual Studio.The MoveDataContext class was generated by the Visual Studio Object Relational Designer.

Запрос LIN'а выполняется против DataContext для извлечения всех фильмов из таблицы базы данных tblMovies.A LINQ query is performed against the DataContext to retrieve all of the movies from the tblMovies database table. Список фильмов присваивается локальной переменной под названием movies.The list of movies is assigned to a local variable named movies. Наконец, список фильмов передается в представление через данные представления.Finally, the list of movies is passed to the view through view data.

Для того, чтобы показать фильмы, нам необходимо изменить представление индекса.In order to show the movies, we next need to modify the Index view. Представление индекса можно найти в папке «Взгляды» (Home).You can find the Index view in the Views\Home\ folder. Обновите представление индекса так, чтобы оно выглядело как представление в листинге 2.Update the Index view so that it looks like the view in Listing 2.

Список 2 -Views\Home\Index.aspxListing 2 – Views\Home\Index.aspx

<%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="false" CodeBehind="Index.aspx.vb" Inherits="MvcApplication1.Index" %>
<%@ Import Namespace="MvcApplication1" %>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

<ul>
<%  For Each m As Movie In ViewData.Model%>
    <li><%= m.Title %></li>
<% Next%>
</ul>
</asp:Content>

Обратите внимание, что измененное представление индекса включает в себя директиву <%' в области имен импорта%> в верхней части представления.Notice that the modified Index view includes an <%@ import namespace %> directive at the top of the view. Эта директива импортирует пространство имен MvcApplication1.This directive imports the MvcApplication1 namespace. Нам нужно это пространство имен для того, чтобы работать с классами моделей - в частности, с классом Movie - в представлении.We need this namespace in order to work with the model classes – in particular, the Movie class -- in the view.

Представление в листинге 2 содержит цикл For Each, который итерируется через все элементы, представленные свойством ViewData.Model.The view in Listing 2 contains a For Each loop that iterates through all of the items represented by the ViewData.Model property. Значение свойства Title отображается для каждого фильма.The value of the Title property is displayed for each movie.

Обратите внимание, что значение свойства ViewData.Model отлито в IEnumerable.Notice that the value of the ViewData.Model property is cast to an IEnumerable. Это необходимо для того, чтобы просачиться содержимое ViewData.Model.This is necessary in order to loop through the contents of ViewData.Model. Другим вариантом здесь является создание сильно набранного представления.Another option here is to create a strongly-typed view. При создании сильно набранного представления вы отбрасываете свойство ViewData.Model в определенный тип в классе кода представления.When you create a strongly-typed view, you cast the ViewData.Model property to a particular type in a view's code-behind class.

Если вы запустите приложение после изменения класса HomeController и представления индекса, то вы получите пустую страницу.If you run the application after modifying the HomeController class and the Index view then you will get a blank page. Вы получите пустую страницу, потому что в таблице базы данных tblMovies нет записей фильмов.You'll get a blank page because there are no movie records in the tblMovies database table.

Чтобы добавить записи в таблицу базы данных tblMovies, нажмите правой кнопкой мыши таблицу базы данных tblMovies в окне Server Explorer (окно Database Explorer в Visual Web Developer) и выберите вариант меню Показать таблицы данных.In order to add records to the tblMovies database table, right-click the tblMovies database table in the Server Explorer window (Database Explorer window in Visual Web Developer) and select the menu option Show Table Data. Записи фильмов можно вставить с помощью появляется сетка (см. рисунок 5).You can insert movie records by using the grid that appears (see Figure 5).

Вставка фильмовInserting movies

Рисунок 06: Вставка фильмов(Нажмите, чтобы посмотреть полноразмерное изображение)Figure 06: Inserting movies(Click to view full-size image)

После добавления некоторых записей баз данных в таблицу tblMovies и запуска приложения вы увидите страницу на рисунке 7.After you add some database records to the tblMovies table, and you run the application, you'll see the page in Figure 7. Все записи базы данных фильмов отображаются в списке.All of the movie database records are displayed in a bulleted list.

Отображение фильмов с представлением индексаDisplaying movies with the Index view

Рисунок 07: Отображение фильмов с представлением индекса(Нажмите, чтобы просмотреть полноразмерное изображение)Figure 07: Displaying movies with the Index view(Click to view full-size image)

Использование шаблона репозиторияUsing the Repository Pattern

В предыдущем разделе мы использовали lin's для классов S'L непосредственно в рамках действия контроллера.In the previous section, we used LINQ to SQL classes directly within a controller action. Мы использовали класс MovieDataContext непосредственно из действия контроллера Index()We used the MovieDataContext class directly from the Index() controller action. Нет ничего плохого в этом в случае простого приложения.There is nothing wrong with doing this in the case of a simple application. Тем не менее, работа непосредственно с LIN'а к S'L в классе контроллера создает проблемы, когда вам нужно построить более сложное приложение.However, working directly with LINQ to SQL in a controller class creates problems when you need to build a more complex application.

Использование LIN'а для S'L в классе контроллеров затрудняет переключение технологий доступа к данным в будущем.Using LINQ to SQL within a controller class makes it difficult to switch data access technologies in the future. Например, можно принять решение о переходе от использования Microsoft LIN' к S-L к использованию рамочной программы Сущности Майкрософт в качестве технологии доступа к данным.For example, you might decide to switch from using Microsoft LINQ to SQL to using the Microsoft Entity Framework as your data access technology. В этом случае необходимо переписать каждый контроллер, который получает доступ к базе данных в приложении.In that case, you would need to rewrite every controller that accesses the database within your application.

Использование LIN's для S'L в классе контроллеров также затрудняет создание модульных тестов для вашего приложения.Using LINQ to SQL within a controller class also makes it difficult to build unit tests for your application. Обычно при выполнении модульных тестов не требуется взаимодействовать с базой данных.Normally, you do not want to interact with a database when performing unit tests. Вы хотите использовать модульные тесты для проверки логики приложения, а не сервера базы данных.You want to use your unit tests to test your application logic and not your database server.

Для того, чтобы создать приложение MVC, которое более адаптируется к будущим изменениям и которое может быть более легко протестировано, следует рассмотреть возможность использования шаблона репозитория.In order to build an MVC application that is more adaptable to future change and that can be more easily tested, you should consider using the Repository pattern. При использовании шаблона репозитория создается отдельный класс репозитория, содержащий всю логику доступа к базе данных.When you use the Repository pattern, you create a separate repository class that contains all of your database access logic.

При создании класса репозитория создается интерфейс, представляющий все методы, используемые классом репозитория.When you create the repository class, you create an interface that represents all of the methods used by the repository class. В контроллерах вы пишете свой код против интерфейса, а не для репозитория.Within your controllers, you write your code against the interface instead of the repository. Таким образом, в будущем можно реализовать репозиторий с использованием различных технологий доступа к данным.That way, you can implement the repository using different data access technologies in the future.

Интерфейс в листинге 3 называется IMovieRepository и представляет собой единый метод под названием ListAll().The interface in Listing 3 is named IMovieRepository and it represents a single method named ListAll().

Список 3 -Models\IMovieRepository.vbListing 3 – Models\IMovieRepository.vb

Public Interface IMovieRepository
     Function ListAll() As IList(Of Movie)
End Interface

Класс репозитория в листинге 4 реализует интерфейс IMovieRepository.The repository class in Listing 4 implements the IMovieRepository interface. Обратите внимание, что он содержит метод под названием ListAll(), который соответствует методу, требуемому интерфейсом IMovieRepository.Notice that it contains a method named ListAll() that corresponds to the method required by the IMovieRepository interface.

Список 4 -Models\MovieRepository.vbListing 4 – Models\MovieRepository.vb

Public Class MovieRepository Implements IMovieRepository
         Private _dataContext As MovieDataContext

         Public Sub New()
              _dataContext = New MovieDataContext()
         End Sub

         Public Function ListAll() As IList(Of Movie) Implements IMovieRepository.ListAll
              Dim movies = From m In _dataContext.Movies _
                   Select m
              Return movies.ToList()
         End Function
End Class

Наконец, класс MoviesController в листинге 5 использует шаблон репозитория.Finally, the MoviesController class in Listing 5 uses the Repository pattern. Он больше не использует LIN'l для непосредственного использования классов S'L.It no longer uses LINQ to SQL classes directly.

Список 5 -Controllers\MoviesController.vbListing 5 – Controllers\MoviesController.vb

using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
    Public Class MoviesController 
        Inherits System.Web.Mvc.Controller

             Private _repository As IMovieRepository

             Sub New()
                  Me.New(New MovieRepository())
             End Sub

             Sub New(ByVal repository As IMovieRepository)
                  _repository = repository
             End Sub

             Function Index()
                  Return View(_repository.ListAll())
             End Function
    End Class
}

Обратите внимание, что в классе MoviesController в листинге 5 есть два конструктора.Notice that the MoviesController class in Listing 5 has two constructors. Первый конструктор, без параметров конструктор, вызывается при запуске приложения.The first constructor, the parameterless constructor, is called when your application is running. Этот конструктор создает экземпляр класса MovieRepository и передает его второму конструктору.This constructor creates an instance of the MovieRepository class and passes it to the second constructor.

Второй конструктор имеет один параметр: параметр IMovieRepository.The second constructor has a single parameter: an IMovieRepository parameter. Этот конструктор просто присваивает значение параметра области _уровня класса, названной репозиторием.This constructor simply assigns the value of the parameter to a class-level field named _repository.

Класс MoviesController использует шаблон проектирования программного обеспечения, называемый шаблоном инъекций зависимости.The MoviesController class is taking advantage of a software design pattern called the Dependency Injection pattern. В частности, он использует так называемый инъекций зависимости конструктора.In particular, it is using something called Constructor Dependency Injection. Вы можете прочитать больше об этой модели, прочитав следующую статью Мартина Фаулера:You can read more about this pattern by reading the following article by Martin Fowler:

http://martinfowler.com/articles/injection.html

Обратите внимание, что весь код в классе MoviesController (за исключением первого конструктора) взаимодействует с интерфейсом IMovieRepository вместо фактического класса MovieRepository.Notice that all of the code in the MoviesController class (with the exception of the first constructor) interacts with the IMovieRepository interface instead of the actual MovieRepository class. Код взаимодействует с абстрактным интерфейсом вместо конкретной реализации интерфейса.The code interacts with an abstract interface instead of a concrete implementation of the interface.

Если вы хотите изменить технологию доступа к данным, используемую приложением, то вы можете просто реализовать интерфейс IMovieRepository с классом, который использует альтернативную технологию доступа к базе данных.If you want to modify the data access technology used by the application then you can simply implement the IMovieRepository interface with a class that uses the alternative database access technology. Например, можно создать класс EntityFrameworkMovieRepository или класс SubSonicMovieRepository.For example, you could create an EntityFrameworkMovieRepository class or a SubSonicMovieRepository class. Поскольку класс контроллера запрограммирован на интерфейс, вы можете передать новую реализацию IMovieRepository классу контроллера, и класс будет продолжать работать.Because the controller class is programmed against the interface, you can pass a new implementation of IMovieRepository to the controller class and the class would continue to work.

Кроме того, если вы хотите протестировать класс MoviesController, то вы можете передать поддельный класс репозитория фильмов в MoviesController.Furthermore, if you want to test the MoviesController class, then you can pass a fake movie repository class to the MoviesController. Вы можете реализовать класс IMovieRepository с классом, который на самом деле не имеет доступа к базе данных, но содержит все необходимые методы интерфейса IMovieRepository.You can implement the IMovieRepository class with a class that does not actually access the database but contains all of the required methods of the IMovieRepository interface. Таким образом, вы можете уединить тест класса MoviesController без фактического доступа к реальной базе данных.That way, you can unit test the MoviesController class without actually accessing a real database.

СводкаSummary

Цель этого руководства состояла в том, чтобы продемонстрировать, как можно создавать классы моделей MVC, воспользовавшись преимуществами Microsoft LIN' для S'L.The goal of this tutorial was to demonstrate how you can create MVC model classes by taking advantage of Microsoft LINQ to SQL. Мы рассмотрели две стратегии отображения данных базы данных в ASP.NET mVC-приложении.We examined two strategies for displaying database data in an ASP.NET MVC application. Во-первых, мы создали lin's для классов S'L и использовали классы непосредственно в рамках действия контроллера.First, we created LINQ to SQL classes and used the classes directly within a controller action. Использование классов LIN's в рамках контроллера позволяет быстро и легко отображать данные базы данных в приложении MVC.Using LINQ to SQL classes within a controller enables you to quickly and easily display database data in an MVC application.

Далее мы исследовали немного более сложный, но определенно более добродетельный путь для отображения данных базы данных.Next, we explored a slightly more difficult, but definitely more virtuous, path for displaying database data. Мы воспользовались шаблоном репозитория и поместили всю логику доступа к базе данных в отдельный класс репозитория.We took advantage of the Repository pattern and placed all of our database access logic in a separate repository class. В нашем контроллере, мы написали все наши коды против интерфейса, а не конкретный класс.In our controller, we wrote all of our code against an interface instead of a concrete class. Преимущество шаблона репозитория заключается в том, что он позволяет нам легко менять технологии доступа к базам данных в будущем, и это позволяет нам легко тестировать наши классы контроллеров.The advantage of the Repository pattern is that it enables us to easily change database access technologies in the future and it enables us to easily test our controller classes.