Modelklassen maken met LINQ naar SQL (C#)

door Microsoft

PDF downloaden

Het doel van deze zelfstudie is het uitleggen van één methode voor het maken van modelklassen voor een ASP.NET MVC-toepassing. In deze zelfstudie leert u hoe u modelklassen bouwt en databasetoegang uitvoert door gebruik te maken van Microsoft LINQ naar SQL.

Het doel van deze zelfstudie is het uitleggen van één methode voor het maken van modelklassen voor een ASP.NET MVC-toepassing. In deze zelfstudie leert u hoe u modelklassen bouwt en databasetoegang uitvoert door gebruik te maken van Microsoft LINQ naar SQL

In deze zelfstudie bouwen we een eenvoudige filmdatabasetoepassing. We beginnen met het maken van de filmdatabasetoepassing op de snelste en eenvoudigste manier. We voeren al onze gegevenstoegang rechtstreeks vanuit onze controlleracties uit.

Vervolgens leert u hoe u het Repository-patroon gebruikt. Voor het gebruik van het patroon Opslagplaats is iets meer werk vereist. Het voordeel van het toepassen van dit patroon is echter dat u hiermee toepassingen kunt bouwen die kunnen worden aangepast aan verandering en eenvoudig kunnen worden getest.

Wat is een modelklasse?

Een MVC-model bevat alle toepassingslogica die niet is opgenomen in een MVC-weergave of MVC-controller. Een MVC-model bevat met name alle bedrijfs- en gegevenstoegangslogica van uw toepassing.

U kunt verschillende technologieën gebruiken om uw logica voor gegevenstoegang te implementeren. U kunt bijvoorbeeld uw gegevenstoegangsklassen bouwen met behulp van microsoft Entity Framework, NHibernate, Subsonic of ADO.NET klassen.

In deze zelfstudie gebruik ik LINQ voor SQL om de database op te vragen en bij te werken. LINQ naar SQL biedt u een zeer eenvoudige manier om te communiceren met een Microsoft SQL Server-database. Het is echter belangrijk om te begrijpen dat het ASP.NET MVC-framework op geen enkele manier is gekoppeld aan LINQ aan SQL. ASP.NET MVC is compatibel met elke technologie voor gegevenstoegang.

Een filmdatabase maken

In deze zelfstudie , om te laten zien hoe u modelklassen kunt bouwen, bouwen we een eenvoudige filmdatabasetoepassing. De eerste stap is het maken van een nieuwe database. Klik met de rechtermuisknop op de map App_Data in het venster Solution Explorer en selecteer de menuoptie Toevoegen, Nieuw item. Selecteer de SQL Server Database-sjabloon , geef deze de naam MoviesDB.mdf en klik op de knop Toevoegen (zie afbeelding 1).

Een nieuwe SQL Server-database toevoegen

Afbeelding 01: Een nieuwe SQL Server-database toevoegen (klik om de volledige afbeelding weer te geven)

Nadat u de nieuwe database hebt gemaakt, kunt u de database openen door te dubbelklikken op het MoviesDB.mdf bestand in de map App_Data. Als u dubbelklikt op het bestand MoviesDB.mdf, wordt het Venster Server Explorer geopend (zie afbeelding 2).

Het Server Explorer-venster wordt het databaseverkennervenster genoemd bij het gebruik van Visual Web Developer.

Schermopname van het venster Server Explorer, waarin wordt weergegeven dat de map Tabellen is gemarkeerd in de maphiërarchie.

Afbeelding 02: Het venster Server Explorer gebruiken (klik om de afbeelding op volledige grootte weer te geven)

We moeten één tabel toevoegen aan onze database die onze films vertegenwoordigt. Klik met de rechtermuisknop op de map Tabellen en selecteer de menuoptie Nieuwe tabel toevoegen. Als u deze menuoptie selecteert, wordt de ontwerpfunctie voor tabellen geopend (zie afbeelding 3).

Schermopname van het Microsoft Visual Studio-venster met de functie Tabelontwerper.

Afbeelding 03: De ontwerpfunctie voor tabellen (klik om de afbeelding op volledige grootte weer te geven)

We moeten de volgende kolommen toevoegen aan de databasetabel:

Kolomnaam Gegevenstype Null-waarden toestaan
Id Int Onwaar
Titel Nvarchar(200) Onwaar
Directeur Nvarchar(50) Onwaar

U moet twee speciale dingen doen aan de kolom Id. Eerst moet u de kolom Id markeren als een primaire-sleutelkolom door de kolom in de tabelontwerper te selecteren en op het pictogram van een sleutel te klikken. LINQ naar SQL vereist dat u de primaire-sleutelkolommen opgeeft bij het uitvoeren van invoegingen of updates voor de database.

Vervolgens moet u de id-kolom markeren als een identiteitskolom door de waarde Ja toe te wijzen aan de eigenschap Is-identiteit (zie afbeelding 3). Een identiteitskolom is een kolom waaraan automatisch een nieuw nummer wordt toegewezen wanneer u een nieuwe rij met gegevens toevoegt aan een tabel.

LINQ maken voor SQL-klassen

Ons MVC-model bevat LINQ naar SQL-klassen die de tblMovie-databasetabel vertegenwoordigen. De eenvoudigste manier om deze LINQ te maken voor SQL-klassen is door met de rechtermuisknop op de map Modellen te klikken, Toevoegen, Nieuw item te selecteren, de LINQ te selecteren voor de sjabloon SQL-klassen, de klassen de naam Movie.dbml te geven en op de knop Toevoegen te klikken (zie afbeelding 4).

LINQ maken voor SQL-klassen

Afbeelding 04: LINQ maken voor SQL-klassen (klik hier om de volledige afbeelding weer te geven)

Direct nadat u de Movie LINQ hebt gemaakt voor SQL-klassen, wordt de object-relationele ontwerpfunctie weergegeven. U kunt databasetabellen vanuit het Server Explorer-venster naar de Object Relational Designer slepen om LINQ te maken naar SQL-klassen die bepaalde databasetabellen vertegenwoordigen. We moeten de tblMovie-databasetabel toevoegen aan de Object Relational Designer (zie afbeelding 5).

Relationele ontwerpfunctie voor objecten gebruiken

Afbeelding 05: De relationele ontwerpfunctie voor objecten gebruiken (klik om de afbeelding op volledige grootte weer te geven)

De Object Relational Designer maakt standaard een klasse met dezelfde naam als de databasetabel die u naar de ontwerpfunctie sleept. We willen onze klas echter niet tblMovie noemen. Klik daarom op de naam van de klas in de ontwerpfunctie en wijzig de naam van de klasse in Film.

Vergeet ten slotte niet om op de knop Opslaan (de afbeelding van de diskette) te klikken om de LINQ op te slaan in SQL-klassen. Anders wordt de LINQ naar SQL-klassen niet gegenereerd door de Object Relational Designer.

LINQ gebruiken voor SQL in een controlleractie

Nu we onze LINQ naar SQL-klassen hebben, kunnen we deze klassen gebruiken om gegevens op te halen uit de database. In deze sectie leert u hoe u LINQ kunt gebruiken voor SQL-klassen rechtstreeks binnen een controlleractie. De lijst met films uit de databasetabel tblMovies wordt weergegeven in een MVC-weergave.

Eerst moeten we de klasse HomeController wijzigen. Deze klasse vindt u in de map Controllers van uw toepassing. Wijzig de klasse zodat deze eruitziet als de klasse in Vermelding 1.

Lijst 1 – Controllers\HomeController.cs

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

namespace MvcApplication1.Controllers
{
     [HandleError]
     public class HomeController : Controller
     {
          public ActionResult Index()
          {
               var dataContext = new MovieDataContext();
               var movies = from m in dataContext.Movies
                    select m;
               return View(movies);
          }
     }
}

De Index() actie in Vermelding 1 gebruikt een LINQ voor SQL DataContext-klasse (de MovieDataContext) om de MoviesDB database weer te geven. De MoveDataContext klasse is gegenereerd door visual Studio Object Relational Designer.

Er wordt een LINQ-query uitgevoerd op basis van DataContext om alle films uit de tblMovies databasetabel op te halen. De lijst met films wordt toegewezen aan een lokale variabele met de naam movies. Ten slotte wordt de lijst met films via de view-data doorgegeven aan de weergave.

Om de films weer te geven, moeten we vervolgens de indexweergave wijzigen. U vindt de indexweergave in de Views\Home\ map. Werk de indexweergave zo bij dat deze eruitziet als de weergave in Vermelding 2.

Lijst 2 – Views\Home\Index.aspx

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index" %>
<%@ Import Namespace="MvcApplication1.Models" %>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

     <ul>
          <% foreach (Movie m in (IEnumerable)ViewData.Model)

          { %>
               <li> <%= m.Title %> </li>
          <% } %>
     </ul>
</asp:Content>

U ziet dat de gewijzigde indexweergave boven aan de weergave een <%@ import namespace %> instructie bevat. Deze richtlijn importeert de MvcApplication1.Models namespace. We hebben deze naamruimte nodig om te kunnen werken met de model klassen, met name de Movie klasse, in de weergave.

De weergave in Vermelding 2 bevat een foreach lus die alle items doorloopt die door de ViewData.Model eigenschap worden vertegenwoordigd. De waarde van de Title eigenschap wordt voor elke movieeigenschap weergegeven.

U ziet dat de waarde van de ViewData.Model eigenschap wordt omgezet in een IEnumerable. Dit is noodzakelijk om door de inhoud van ViewData.Model te lopen. Een andere optie hier is het maken van een sterk getypte view. Wanneer u een sterk getypte view maakt, cast u de ViewData.Model-eigenschap naar een bepaald type in de achterliggende codeklasse van een weergave.

Als u de toepassing uitvoert nadat u de HomeController klasse en de indexweergave hebt gewijzigd, krijgt u een lege pagina. U krijgt een lege pagina omdat er geen filmrecords in de tblMovies databasetabel staan.

Als u records wilt toevoegen aan de databasetabel, klikt u met de tblMovies rechtermuisknop op de tblMovies databasetabel in het Server Explorer-venster (databaseverkennervenster in Visual Web Developer) en selecteert u de menuoptie Tabelgegevens weergeven. U kunt records invoegen movie met behulp van het raster dat wordt weergegeven (zie afbeelding 6).

Films invoegen

Afbeelding 06: Films invoegen (Klik om de afbeelding op volledige grootte weer te geven)

Nadat u enkele databaserecords aan de tblMovies tabel hebt toegevoegd en u de toepassing uitvoert, ziet u de pagina in afbeelding 7. Alle filmdatabaserecords worden weergegeven in een opsomming.

Films weergeven met de indexweergave

Afbeelding 07: Films weergeven met de indexweergave (klik om de afbeelding op volledige grootte weer te geven)

Het opslagplaatspatroon gebruiken

In de vorige sectie hebben we LINQ rechtstreeks in een controlleractie gebruikt voor SQL-klassen. We hebben de MovieDataContext klasse rechtstreeks vanuit de Index() controlleractie gebruikt. Er is niets mis met dit in het geval van een eenvoudige toepassing. Als u echter rechtstreeks met LINQ naar SQL werkt in een controllerklasse, ontstaan er problemen wanneer u een complexere toepassing moet bouwen.

Het gebruik van LINQ naar SQL binnen een controllerklasse maakt het lastig om in de toekomst over te schakelen tussen technologieën voor gegevenstoegang. U kunt bijvoorbeeld besluiten om over te schakelen van Het gebruik van Microsoft LINQ naar SQL naar het Microsoft Entity Framework als uw technologie voor gegevenstoegang. In dat geval moet u elke controller die toegang heeft tot de database in uw toepassing opnieuw schrijven.

Het gebruik van LINQ naar SQL binnen een controllerklasse maakt het ook moeilijk om eenheidstests voor uw toepassing te bouwen. Normaal gesproken wilt u geen interactie met een database uitvoeren bij het uitvoeren van eenheidstests. U wilt uw eenheidstests gebruiken om uw toepassingslogica te testen en niet uw databaseserver.

Als u een MVC-toepassing wilt bouwen die beter kan worden aangepast aan toekomstige wijzigingen en die gemakkelijker kunnen worden getest, moet u overwegen het patroon Opslagplaats te gebruiken. Wanneer u het patroon Opslagplaats gebruikt, maakt u een afzonderlijke opslagplaatsklasse die al uw databasetoegangslogica bevat.

Wanneer u de opslagplaatsklasse maakt, maakt u een interface die alle methoden vertegenwoordigt die door de opslagplaatsklasse worden gebruikt. Binnen uw controllers schrijft u uw code op basis van de interface in plaats van de opslagplaats. Op die manier kunt u de opslagplaats implementeren met behulp van verschillende technologieën voor gegevenstoegang in de toekomst.

De interface in Vermelding 3 heeft een naam IMovieRepository en vertegenwoordigt één methode met de naam ListAll().

Lijst 3 – Models\IMovieRepository.cs

using System.Collections.Generic;
namespace MvcApplication1.Models
{
     public interface IMovieRepository
     {
          IList<Movie> ListAll();
     }
}

De opslagplaatsklasse in Listing 4 implementeert de IMovieRepository interface. Het bevat een methode genaamd ListAll(), die overeenkomt met de methode die is vereist door de IMovieRepository-interface.

Lijst 4 – Models\MovieRepository.cs

using System.Collections.Generic;
using System.Linq;

namespace MvcApplication1.Models
{
     public class MovieRepository : IMovieRepository
     {
          private MovieDataContext _dataContext;

          public MovieRepository()
          {
                _dataContext = new MovieDataContext();
          }

          #region IMovieRepository Members

          public IList<Movie> ListAll()
          {
               var movies = from m in _dataContext.Movies
                    select m;
               return movies.ToList();
          }

          #endregion
     }
}

Ten slotte maakt de MoviesController klasse in Listing 5 gebruik van het opslagplaatspatroon. LinQ wordt niet meer rechtstreeks gebruikt voor SQL-klassen.

Vermelding 5 – Controllers\MoviesController.cs

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

namespace MvcApplication1.Controllers
{
     public class MoviesController : Controller
     {
          private IMovieRepository _repository;

          public MoviesController() : this(new MovieRepository())
          {
          }

          public MoviesController(IMovieRepository repository)
          {
               _repository = repository;
          }

          public ActionResult Index()
          {
               return View(_repository.ListAll());
          }
     }
}

U ziet dat de MoviesController klasse in Listing 5 twee constructors heeft. De eerste constructor, de parameterloze constructor, wordt aangeroepen wanneer uw toepassing wordt uitgevoerd. Met deze constructor wordt een exemplaar van de MovieRepository klasse gemaakt en doorgegeven aan de tweede constructor.

De tweede constructor heeft één parameter: een IMovieRepository parameter. Met deze constructor wordt simpelweg de waarde van de parameter toegewezen aan een veld op klasseniveau met de naam _repository.

De MoviesController klasse maakt gebruik van een softwareontwerppatroon dat het patroon Afhankelijkheidsinjectie wordt genoemd. In het bijzonder wordt er gebruikgemaakt van iets dat constructorafhankelijkheidsinjectie wordt genoemd. Lees het volgende artikel van Martin Fowler voor meer informatie over dit patroon:

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

U ziet dat alle code in de MoviesController klasse (met uitzondering van de eerste constructor) communiceert met de IMovieRepository interface in plaats van de werkelijke MovieRepository klasse. De code communiceert met een abstracte interface in plaats van een concrete implementatie van de interface.

Als u de technologie voor gegevenstoegang wilt wijzigen die door de toepassing wordt gebruikt, kunt u gewoon de IMovieRepository interface implementeren met een klasse die gebruikmaakt van de alternatieve technologie voor databasetoegang. U kunt bijvoorbeeld een EntityFrameworkMovieRepository klas of een SubSonicMovieRepository klasse maken. Omdat de controllerklasse is geprogrammeerd op basis van de interface, kunt u een nieuwe implementatie doorgeven aan IMovieRepository de controllerklasse en blijft de klasse werken.

Bovendien, als je de klasse wilt testen MoviesController , kun je een nep filmopslagplaatsklasse doorgeven aan de HomeController. U kunt de IMovieRepository klasse implementeren met een klasse die geen toegang heeft tot de database, maar die alle vereiste methoden van de IMovieRepository interface bevat. Op die manier kunt u de MoviesController klasse testen zonder daadwerkelijk toegang te krijgen tot een echte database.

Overzicht

Het doel van deze zelfstudie was om te laten zien hoe u MVC-modelklassen kunt maken door te profiteren van Microsoft LINQ naar SQL. We hebben twee strategieën onderzocht voor het weergeven van databasegegevens in een ASP.NET MVC-toepassing. Eerst hebben we LINQ gemaakt voor SQL-klassen en de klassen rechtstreeks in een controlleractie gebruikt. Met LINQ naar SQL-klassen binnen een controller kunt u snel en eenvoudig databasegegevens weergeven in een MVC-toepassing.

Vervolgens hebben we een iets moeilijker, maar zeker meer correct pad voor het weergeven van databasegegevens verkend. We hebben gebruikgemaakt van het patroon Opslagplaats en hebben al onze databasetoegangslogica in een afzonderlijke opslagplaatsklasse geplaatst. In onze controller hebben we al onze code geschreven tegen een interface in plaats van een concrete klasse. Het voordeel van het opslagplaatspatroon is dat we in de toekomst eenvoudig databasetoegangstechnologieën kunnen wijzigen en dat we onze controllerklassen eenvoudig kunnen testen.