Condividi tramite


Creazione di classi di modelli con LINQ to SQL (C#)

di Microsoft

Scaricare il PDF

L'obiettivo di questa esercitazione è illustrare un metodo per la creazione di classi di modelli per un'applicazione MVC ASP.NET. In questa esercitazione si apprenderà come creare classi di modelli ed eseguire l'accesso al database sfruttando Microsoft LINQ to SQL.

L'obiettivo di questa esercitazione è illustrare un metodo per la creazione di classi di modelli per un'applicazione MVC ASP.NET. In questa esercitazione si apprenderà come creare classi di modelli ed eseguire l'accesso al database sfruttando Microsoft LINQ to SQL

In questa esercitazione viene creata un'applicazione di database Movie di base. Per iniziare, si crea l'applicazione di database Movie nel modo più rapido e più semplice possibile. Tutti gli accessi ai dati vengono eseguiti direttamente dalle azioni del titolare del trattamento.

Si apprenderà quindi come usare il modello repository. L'uso del modello repository richiede un po' di lavoro. Tuttavia, il vantaggio dell'adozione di questo modello è che consente di creare applicazioni adattabili alle modifiche e di essere facilmente testate.

Che cos'è una classe modello?

Un modello MVC contiene tutta la logica dell'applicazione non contenuta in una visualizzazione MVC o in un controller MVC. In particolare, un modello MVC contiene tutta la logica di accesso ai dati e aziendali dell'applicazione.

È possibile usare un'ampia gamma di tecnologie diverse per implementare la logica di accesso ai dati. Ad esempio, è possibile compilare le classi di accesso ai dati usando le classi Microsoft Entity Framework, NHibernate, Subsonic o ADO.NET.

In questa esercitazione si usa LINQ to SQL per eseguire query e aggiornare il database. LINQ to SQL offre un metodo molto semplice per interagire con un database di Microsoft SQL Server. Tuttavia, è importante comprendere che il framework MVC ASP.NET non è associato a LINQ to SQL in alcun modo. ASP.NET MVC è compatibile con qualsiasi tecnologia di accesso ai dati.

Creare un database di film

In questa esercitazione, per illustrare come creare classi di modelli, viene creata una semplice applicazione di database Movie. Il primo passaggio consiste nel creare un nuovo database. Fare clic con il pulsante destro del mouse sulla cartella App_Data nella finestra Esplora soluzioni e scegliere l'opzione di menu Aggiungi, Nuovo elemento. Selezionare il modello di database di SQL Server , assegnare il nome MoviesDB.mdf e fare clic sul pulsante Aggiungi (vedere la figura 1).

Aggiunta di un nuovo database di SQL Server

Figura 01: Aggiunta di un nuovo database di SQL Server (fare clic per visualizzare l'immagine a dimensione intera)

Dopo aver creato il nuovo database, è possibile aprire il database facendo doppio clic sul file MoviesDB.mdf nella cartella App_Data. Facendo doppio clic sul file MoviesDB.mdf si apre la finestra Esplora server (vedere la figura 2).

La finestra Esplora server viene chiamata finestra Esplora database quando si usa Visual Web Developer.

Screenshot della finestra Esplora server, che mostra che la cartella Tabelle è evidenziata nella gerarchia di cartelle.

Figura 02: Uso della finestra Esplora server (fare clic per visualizzare l'immagine a dimensione intera)

È necessario aggiungere una tabella al database che rappresenta i film. Fare clic con il pulsante destro del mouse sulla cartella Tabelle e scegliere l'opzione di menu Aggiungi nuova tabella. Selezionando questa opzione di menu si apre Progettazione tabelle (vedere la figura 3).

Screenshot della finestra di Microsoft Visual Studio, che mostra la funzionalità Progettazione tabelle.

Figura 03: Progettazione tabelle (fare clic per visualizzare l'immagine a dimensione intera)

È necessario aggiungere le colonne seguenti alla tabella di database:

Nome colonna Tipo di dati Consenti valori Null
ID Intero Falso
Titolo Nvarchar(200) Falso
Direttore Nvarchar(50) Falso

È necessario eseguire due operazioni speciali per la colonna ID. Prima di tutto, è necessario contrassegnare la colonna ID come colonna chiave primaria selezionando la colonna in Progettazione tabelle e facendo clic sull'icona di una chiave. LINQ to SQL richiede di specificare le colonne di chiave primaria durante l'esecuzione di inserimenti o aggiornamenti sul database.

Successivamente, è necessario contrassegnare la colonna Id come colonna Identity assegnando il valore Sì alla proprietà Is Identity (vedere la figura 3). Una colonna Identity è una colonna a cui viene assegnato automaticamente un nuovo numero ogni volta che si aggiunge una nuova riga di dati a una tabella.

Creare classi LINQ per SQL

Il modello MVC conterrà classi LINQ to SQL che rappresentano la tabella di database tblMovie. Il modo più semplice per creare queste classi LINQ to SQL consiste nel fare clic con il pulsante destro del mouse sulla cartella Modelli, scegliere Aggiungi, Nuovo elemento, selezionare il modello Classi LINQ to SQL, assegnare alle classi il nome Movie.dbml e fare clic sul pulsante Aggiungi (vedere la figura 4).

Creazione di classi LINQ to SQL

Figura 04: Creazione di classi LINQ to SQL (fare clic per visualizzare l'immagine a dimensione intera)

Subito dopo aver creato le classi MOVIE LINQ to SQL, viene visualizzata la finestra di progettazione relazionale oggetti. È possibile trascinare le tabelle di database dalla finestra Esplora server in Progettazione relazionale oggetti per creare classi LINQ to SQL che rappresentano tabelle di database specifiche. È necessario aggiungere la tabella di database tblMovie in Progettazione relazionale oggetti (vedere la figura 5).

Utilizzo del progettista relazionale degli oggetti

Figura 05: Utilizzo di Progettazione relazionale oggetti (fare clic per visualizzare l'immagine a dimensione intera)

Per impostazione predefinita, l'Object Relational Designer crea una classe con lo stesso nome della tabella del database trascinata sul Designer. Tuttavia, non vogliamo chiamare la nostra classe tblMovie. Di conseguenza, fare clic sul nome della classe in Progettazione e modificare il nome della classe in Movie.

Infine, ricordarsi di fare clic sul pulsante Salva (immagine del floppy) per salvare le classi LINQ to SQL. In caso contrario, le classi LINQ to SQL non verranno generate dal Designer relazionale a oggetti.

Uso di LINQ to SQL in un'azione del controller

Ora che sono disponibili le classi LINQ to SQL, è possibile usare queste classi per recuperare i dati dal database. In questa sezione viene illustrato come usare le classi LINQ to SQL direttamente all'interno di un'azione del controller. Verrà visualizzato l'elenco dei film della tabella di database tblMovies in una visualizzazione MVC.

Prima di tutto, è necessario modificare la classe HomeController. Questa classe è disponibile nella cartella Controllers dell'applicazione. Modificare la classe in modo che sia simile alla classe nell'elenco 1.

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

L'azione Index() nell'elenco 1 usa una classe LINQ to SQL DataContext (la MovieDataContext) per rappresentare il MoviesDB database. La MoveDataContext classe è stata generata da Progettazione relazionale oggetti di Visual Studio.

Una query LINQ viene eseguita su DataContext per recuperare tutti i film dalla tblMovies tabella di database. L'elenco di film viene assegnato a una variabile locale denominata movies. Infine, l'elenco dei film viene passato alla visualizzazione tramite i dati di visualizzazione.

Per visualizzare i film, è necessario modificare la visualizzazione Indice. È possibile trovare la visualizzazione Indice nella Views\Home\ cartella . Aggiornare la visualizzazione Indice in modo che abbia un aspetto simile alla visualizzazione nell'elenco 2.

Presentazione 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>

Si noti che la visualizzazione Indice modificata include una <%@ import namespace %> direttiva nella parte superiore della visualizzazione. Questa direttiva importa il MvcApplication1.Models namespace. Abbiamo bisogno di questo namespace per lavorare con la classe model, in particolare con la classe Movie, all'interno della vista.

La visualizzazione nell'Elenco 2 contiene un foreach ciclo che itera su tutti gli elementi rappresentati dalla proprietà ViewData.Model. Il valore della proprietà Title viene visualizzato per ogni movie.

Si noti che il valore della proprietà viene convertito in un IEnumerable. Questa operazione è necessaria per scorrere il contenuto di ViewData.Model. Un'altra opzione consiste nel creare un view fortemente tipizzato. Quando si crea un oggetto fortemente tipizzato view, si esegue il cast della proprietà ViewData.Model a un particolare tipo nella classe di code-behind di una vista.

Se si esegue l'applicazione dopo aver modificato la HomeController classe e la visualizzazione Indice, si otterrà una pagina vuota. Si otterrà una pagina vuota perché nella tabella di tblMovies database non sono presenti record di film.

Per aggiungere record alla tblMovies tabella di database, fare clic con il pulsante destro del mouse sulla tblMovies tabella di database nella finestra Esplora server (finestra Esplora database in Visual Web Developer) e scegliere l'opzione di menu Mostra dati tabella. È possibile inserire movie record usando la griglia visualizzata (vedere la figura 6).

Inserimento di film

Figura 06: Inserimento di film (fare clic per visualizzare l'immagine a dimensione intera)

Dopo aver aggiunto alcuni record di database alla tblMovies tabella ed è stata eseguita l'applicazione, verrà visualizzata la pagina nella figura 7. Tutti i record del database dei film vengono visualizzati in un elenco puntato.

Visualizzazione di film con la visualizzazione Indice

Figura 07: Visualizzazione di film con la visualizzazione Indice (fare clic per visualizzare l'immagine a dimensione intera)

Uso del modello di repository

Nella sezione precedente sono stati usati classi LINQ to SQL direttamente all'interno di un'azione del controller. Abbiamo usato la classe MovieDataContext direttamente dall'azione Index() del controller. Non c'è nulla di sbagliato con questa operazione nel caso di una semplice applicazione. Tuttavia, l'uso diretto di LINQ to SQL in una classe controller crea problemi quando è necessario compilare un'applicazione più complessa.

L'uso di LINQ to SQL all'interno di una classe controller rende difficile cambiare le tecnologie di accesso ai dati in futuro. Ad esempio, è possibile decidere di passare dall'uso di Microsoft LINQ a SQL all'uso di Microsoft Entity Framework come tecnologia di accesso ai dati. In tal caso, sarebbe necessario riscrivere ogni controller che accede al database all'interno dell'applicazione.

L'uso di LINQ to SQL all'interno di una classe controller rende anche difficile compilare unit test per l'applicazione. In genere, non si vuole interagire con un database quando si eseguono unit test. Si vogliono usare gli unit test per testare la logica dell'applicazione e non il server di database.

Per creare un'applicazione MVC più adattabile alla modifica futura e che può essere testata più facilmente, è consigliabile usare il modello repository. Quando si usa il modello Repository, si crea una classe di repository separata che contiene tutta la logica di accesso al database.

Quando si crea la classe del repository, si crea un'interfaccia che rappresenta tutti i metodi usati dalla classe del repository. All'interno dei controller si scrive il codice nell'interfaccia anziché nel repository. In questo modo, è possibile implementare il repository usando tecnologie di accesso ai dati diverse in futuro.

L'interfaccia nell'elenco 3 è denominata IMovieRepository e rappresenta un singolo metodo denominato ListAll().

Presentazione 3 : Models\IMovieRepository.cs

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

La classe del repository nell'elenco 4 implementa l'interfaccia IMovieRepository . Si noti che contiene un metodo denominato ListAll() che corrisponde al metodo richiesto dall'interfaccia IMovieRepository .

Presentazione 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
     }
}

Infine, la classe nell'elenco MoviesController 5 usa il modello Repository. Non usa più direttamente le classi LINQ to SQL.

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

Si noti che la classe MoviesController nel listato 5 ha due costruttori. Il primo costruttore, il costruttore senza parametri, viene chiamato quando l'applicazione è in esecuzione. Questo costruttore crea un'istanza della MovieRepository classe e la passa al secondo costruttore.

Il secondo costruttore ha un singolo parametro: un IMovieRepository parametro. Questo costruttore assegna semplicemente il valore del parametro a un campo a livello di classe denominato _repository.

La MoviesController classe sfrutta un pattern di Dependency Injection, un modello di progettazione software. In particolare, usa qualcosa di chiamato inserimento delle dipendenze del costruttore. Per altre informazioni su questo modello, leggere l'articolo seguente di Martin Fowler:

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

Notare che tutto il codice nella classe MoviesController (ad eccezione del primo costruttore) interagisce con l'interfaccia IMovieRepository invece che con la classe effettiva MovieRepository. Il codice interagisce con un'interfaccia astratta anziché un'implementazione concreta dell'interfaccia.

Se si vuole modificare la tecnologia di accesso ai dati usata dall'applicazione, è sufficiente implementare l'interfaccia IMovieRepository con una classe che usa la tecnologia di accesso al database alternativa. Ad esempio, è possibile creare una EntityFrameworkMovieRepository classe o una SubSonicMovieRepository classe . Poiché la classe controller è programmata rispetto all'interfaccia, è possibile passare una nuova implementazione di IMovieRepository alla classe controller e la classe continuerà a funzionare.

Inoltre, se si vuole testare la MoviesController classe , è possibile passare una classe di repository di film falsi a HomeController. È possibile implementare la IMovieRepository classe con una classe che non accede effettivamente al database ma contiene tutti i metodi necessari dell'interfaccia IMovieRepository . In questo modo, è possibile eseguire unit test della MoviesController classe senza accedere effettivamente a un database reale.

Sommario

L'obiettivo di questa esercitazione è illustrare come creare classi di modelli MVC sfruttando Microsoft LINQ to SQL. Sono state esaminate due strategie per la visualizzazione dei dati del database in un'applicazione MVC ASP.NET. Prima di tutto, sono state create classi LINQ to SQL e sono state usate le classi direttamente all'interno di un'azione del controller. L'uso di classi LINQ to SQL all'interno di un controller consente di visualizzare rapidamente e facilmente i dati del database in un'applicazione MVC.

Successivamente, è stato esaminato un percorso leggermente più difficile, ma decisamente più virtuoso, per la visualizzazione dei dati del database. Il modello Repository è stato sfruttato e inserito tutta la logica di accesso al database in una classe di repository separata. Nel controller è stato scritto tutto il codice su un'interfaccia invece di una classe concreta. Il vantaggio del modello repository è che consente di modificare facilmente le tecnologie di accesso al database in futuro e consente di testare facilmente le classi controller.