Condividi tramite


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

da Microsoft

Scarica il PDF

L'obiettivo di questa esercitazione è spiegare un metodo per la creazione di classi di modello 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 è spiegare un metodo per la creazione di classi di modello per un'applicazione MVC ASP.NET. Questa esercitazione descrive 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. Si inizia creando l'applicazione di database Movie nel modo più veloce e più semplice possibile. L'accesso ai dati viene eseguito 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 che sono adattabili alla modifica e possono essere facilmente testate.

Che cos'è una classe modello?

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

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

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 SQL Server Microsoft. Tuttavia, è importante comprendere che il framework MVC ASP.NET non è legato 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 modello, è possibile creare un'applicazione di database movie semplice. 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 selezionare l'opzione di menu Aggiungi, Nuovo elemento. Selezionare il modello di database SQL Server, assegnargli il nome MoviesDB.mdf e fare clic sul pulsante Aggiungi (vedi figura 1).

Aggiunta di un nuovo database SQL Server

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

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 delle cartelle.

Figura 02: Uso della finestra Esplora server (Fare clic per visualizzare l'immagine full-size)

È necessario aggiungere una tabella al database che rappresenta i film. Fare clic con il pulsante destro del mouse sulla cartella Tabelle e selezionare l'opzione di menu Aggiungi nuova tabella. Se si seleziona questa opzione di menu, viene visualizzata la Designer Tabella (vedere la figura 3).

Screenshot della finestra di Microsoft Visual Studio, che mostra la funzionalità Tabella Designer.

Figura 03: Tabella Designer (Fare clic per visualizzare l'immagine full-size)

È necessario aggiungere le colonne seguenti alla tabella di database:

Nome colonna Tipo di dati Consenti valori NULL
ID Int Falso
Titolo Nvarchar(200) Falso
Responsabile 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 nella tabella Designer e facendo clic sull'icona di una chiave. LINQ to SQL richiede di specificare le colonne chiave primaria durante l'esecuzione di inserimenti o aggiornamenti nel 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 assegnata automaticamente a un nuovo numero ogni volta che si aggiunge una nuova riga di dati a una tabella.

Creare classi LINQ to SQL

Il modello MVC conterrà LINQ to SQL classi che rappresentano la tabella di database tblMovie. Il modo più semplice per creare queste classi di LINQ to SQL consiste nel fare clic con il pulsante destro del mouse sulla cartella Modelli, selezionare 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 dimensioni complete)

Subito dopo aver creato le classi di LINQ to SQL film, viene visualizzato il Object Relational Designer. È possibile trascinare le tabelle di database dalla finestra Esplora server nella Object Relational Designer per creare classi LINQ to SQL che rappresentano tabelle di database specifiche. È necessario aggiungere la tabella di database tblMovie alla Object Relational Designer (vedere la figura 5).

Uso del Object Relational Designer

Figura 05: Uso della Object Relational Designer (Fare clic per visualizzare l'immagine full-size)

Per impostazione predefinita, il Object Relational Designer crea una classe con lo stesso nome della tabella di database trascinata nella Designer. Tuttavia, non si vuole chiamare la classe tblMovie. Fare quindi clic sul nome della classe nella Designer 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 di LINQ to SQL non verranno generate dalla Object Relational Designer.

Uso di LINQ to SQL in un'azione 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 dalla tabella di database tblMovies in una visualizzazione MVC.

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

Elenco 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() in List 1 usa una classe DataContext (dataContextMovieDataContext) LINQ to SQL per rappresentare il MoviesDB database. La MoveDataContext classe è stata generata dalla Object Relational Designer di Visual Studio.

Una query LINQ viene eseguita su DataContext per recuperare tutti i film dalla tabella di tblMovies database. L'elenco dei 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 sia 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 l'oggetto MvcApplication1.Models namespace. È necessario questo spazio dei nomi per usare le model classi, in particolare la Movie classe , nella visualizzazione.

La visualizzazione nell'elenco 2 contiene un foreach ciclo che esegue l'iterazione ViewData.Model di tutti gli elementi rappresentati dalla proprietà. Il valore della Title proprietà viene visualizzato per ogni movieoggetto .

Si noti che il valore della ViewData.Model proprietà viene eseguito il cast in un IEnumerableoggetto . Questa operazione è necessaria per eseguire il ciclo attraverso il contenuto di ViewData.Model. Un'altra opzione è quella di creare un oggetto fortemente tipizzato view. Quando si crea un oggetto fortemente tipizzato view, si esegue il cast della ViewData.Model proprietà in un determinato tipo nella classe code-behind di una vista.

Se si esegue l'applicazione dopo aver modificato la HomeController classe e la visualizzazione Indice, verrà visualizzata una pagina vuota. Verrà visualizzata 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 tblMovies pulsante destro del mouse sulla tabella di database nella finestra Esplora server (finestra Esplora database in Visual Web Developer) e selezionare 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 full-size)

Dopo aver aggiunto alcuni record di database alla tblMovies tabella ed eseguire l'applicazione, verrà visualizzata la pagina nella figura 7. Tutti i record del database del 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 dimensioni complete)

Uso del modello di repository

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

L'uso di LINQ to SQL all'interno di una classe controller rende difficile cambiare tecnologie di accesso ai dati in futuro. Ad esempio, è possibile decidere di passare dall'uso di Microsoft LINQ to SQL all'uso di Microsoft Entity Framework come tecnologia di accesso ai dati. In questo caso, è 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 durante l'esecuzione di unit test. Si desidera usare gli unit test per testare la logica dell'applicazione e non il server di database.

Per creare un'applicazione MVC più adatta alle modifiche future 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 repository, si crea un'interfaccia che rappresenta tutti i metodi usati dalla classe repository. Nei controller si scrive il codice nell'interfaccia anziché nel repository. In questo modo, è possibile implementare il repository usando diverse tecnologie di accesso ai dati in futuro.

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

Elenco 3 – Models\IMovieRepository.cs

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

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

Elenco 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 in List 5 usa il MoviesController modello Repository. Non usa più le classi LINQ to SQL direttamente.

Elenco 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 MoviesController classe in List 5 ha due costruttori. Il primo costruttore, il costruttore senza parametri, viene chiamato quando l'applicazione è in esecuzione. Questo costruttore crea un'istanza MovieRepository della 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 modello di progettazione software denominato modello di inserimento delle dipendenze. In particolare, usa qualcosa di nome Costruttore Dependency Injection. Per altre informazioni su questo modello, leggere l'articolo seguente di Martin Fowler:

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

Si noti che tutto il codice nella MoviesController classe (ad eccezione del primo costruttore) interagisce con l'interfaccia anziché la IMovieRepository 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 con una classe che usa la IMovieRepository tecnologia di accesso al database alternativo. Ad esempio, è possibile creare una classe o una EntityFrameworkMovieRepositorySubSonicMovieRepository classe. Poiché la classe controller è programmata sull'interfaccia, è possibile passare una nuova implementazione della IMovieRepository classe controller e la classe continua a funzionare.

Inoltre, se si vuole testare la MoviesController classe, è possibile passare una classe repository di film falso 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 un unit test della MoviesController classe senza accedere effettivamente a un database reale.

Riepilogo

L'obiettivo di questa esercitazione è stato illustrare come creare classi di modelli MVC sfruttando Microsoft LINQ to SQL. Sono state esaminate due strategie per visualizzare i dati del database in un'applicazione MVC ASP.NET. Prima di tutto, sono state create LINQ to SQL classi e sono state usate le classi direttamente all'interno di un'azione 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 esplorato un percorso leggermente più difficile, ma sicuramente più virtuoso, per visualizzare i dati del database. È stato sfruttato il modello repository e è stata inserita tutta la logica di accesso al database in una classe di repository separata. Nel controller è stato scritto tutto il codice su un'interfaccia anziché su 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.