Bagikan melalui


Bagian 4, tambahkan model ke aplikasi MVC Inti ASP.NET

Catatan

Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Peringatan

Versi ASP.NET Core ini tidak lagi didukung. Untuk informasi selengkapnya, lihat Kebijakan Dukungan .NET dan .NET Core. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Penting

Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.

Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Oleh Rick Anderson dan Jon P Smith.

Dalam tutorial ini, kelas ditambahkan untuk mengelola film dalam database. Kelas-kelas ini adalah bagian "Model" dari aplikasi MVC.

Kelas model ini digunakan dengan Entity Framework Core (EF Core) untuk bekerja dengan database. EF Core adalah kerangka kerja pemetaan relasional objek (ORM) yang menyederhanakan kode akses data yang harus Anda tulis.

Kelas model yang dibuat dikenal sebagai kelas POCO, dari Plain Old CLR Objects. Kelas POCO tidak memiliki dependensi pada EF Core. Mereka hanya menentukan properti data yang akan disimpan dalam database.

Dalam tutorial ini, kelas model dibuat terlebih dahulu, dan EF Core membuat database.

Menambahkan kelas model data

Klik kanan folder >Model Tambahkan>Kelas. Beri nama file Movie.cs.

Models/Movie.cs Perbarui file dengan kode berikut:

using System.ComponentModel.DataAnnotations;

namespace MvcMovie.Models;

public class Movie
{
    public int Id { get; set; }
    public string? Title { get; set; }
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }
    public string? Genre { get; set; }
    public decimal Price { get; set; }
}

Kelas Movie berisi Id bidang, yang diperlukan oleh database untuk kunci utama.

Atribut DataType pada ReleaseDate menentukan jenis data (Date). Dengan atribut ini:

  • Pengguna tidak diharuskan memasukkan informasi waktu di bidang tanggal.
  • Hanya tanggal yang ditampilkan, bukan informasi waktu.

DataAnnotations dibahas dalam tutorial selanjutnya.

Tanda tanya setelah string menunjukkan bahwa properti dapat diubah ke null. Untuk informasi selengkapnya, lihat Jenis nilai yang dapat diubah ke null.

Menambahkan paket NuGet

Visual Studio secara otomatis menginstal paket yang diperlukan.

Buat proyek sebagai pemeriksaan kesalahan pengkompilasi.

Halaman film Perancah

Gunakan alat perancah untuk menghasilkan Createhalaman , , ReadUpdate, dan Delete (CRUD) untuk model film.

Di Penjelajah Solusi, klik kanan folder Pengontrol dan pilih Tambahkan > Item Perancah Baru.

tampilan langkah di atas

Dalam dialog Tambahkan Item Perancah Baru:

  • Di panel kiri, pilih Instal MVC Umum.>>
  • Pilih Pengontrol MVC dengan tampilan, menggunakan Kerangka Kerja Entitas.
  • Pilih Tambahkan.

Tambahkan dialog Perancah

Selesaikan dialog Tambahkan Pengontrol MVC dengan tampilan, menggunakan Kerangka Kerja Entitas:

  • Di menu drop-down Kelas model , pilih Film (MvcMovie.Models).
  • Di baris Kelas konteks data, pilih + tanda (plus).
    • Dalam dialog Tambahkan Konteks Data, nama kelas MvcMovie.Data.MvcMovieContext dihasilkan.
    • Pilih Tambahkan.
  • Di menu drop-down Penyedia database, pilih SQL Server.
  • Tampilan dan Nama pengontrol: Pertahankan default.
  • Pilih Tambahkan.

Menambahkan konteks Data menyimpan default

Jika Anda mendapatkan pesan kesalahan, pilih Tambahkan untuk kedua kalinya untuk mencobanya lagi.

Perancah menambahkan paket berikut:

  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools
  • Microsoft.VisualStudio.Web.CodeGeneration.Design

Perancah membuat hal berikut:

  • Pengontrol film: Controllers/MoviesController.cs
  • Razor lihat file untuk halaman Buat, Hapus, Detail, Edit, dan Indeks : Views/Movies/*.cshtml
  • Kelas konteks database: Data/MvcMovieContext.cs

Perancah memperbarui hal berikut:

  • Menyisipkan referensi paket yang MvcMovie.csproj diperlukan dalam file proyek.
  • Mendaftarkan konteks database dalam Program.cs file.
  • Menambahkan database string koneksi ke appsettings.json file.

Pembuatan otomatis file dan pembaruan file ini dikenal sebagai perancah.

Halaman perancah belum dapat digunakan karena database belum ada. Menjalankan aplikasi dan memilih tautan Aplikasi Film menghasilkan tidak dapat membuka database atau tidak ada tabel seperti itu: Pesan kesalahan film.

Buat aplikasi untuk memverifikasi bahwa tidak ada kesalahan.

Migrasi awal

EF CoreGunakan fitur Migrasi untuk membuat database. Migrasi adalah sekumpulan alat yang membuat dan memperbarui database agar sesuai dengan model data.

Dari menu Alat, pilih Pengelola Paket NuGet>Konsol Pengelola Paket.

Di Package Manager Console (PMC), masukkan perintah berikut:

Add-Migration InitialCreate

  • Add-Migration InitialCreate: Menghasilkan Migrations/{timestamp}_InitialCreate.cs file migrasi. Argumen InitialCreate adalah nama migrasi. Nama apa pun dapat digunakan, tetapi menurut konvensi, nama dipilih yang menjelaskan migrasi. Karena ini adalah migrasi pertama, kelas yang dihasilkan berisi kode untuk membuat skema database. Skema database didasarkan pada model yang ditentukan di MvcMovieContext kelas .

Peringatan berikut ditampilkan, yang ditangani di langkah selanjutnya:

Tidak ada jenis penyimpanan yang ditentukan untuk properti desimal 'Harga' pada jenis entitas 'Film'. Ini akan menyebabkan nilai terpotong secara diam-diam jika tidak cocok dalam presisi dan skala default. Tentukan jenis kolom server SQL secara eksplisit yang dapat mengakomodasi semua nilai di 'OnModelCreating' menggunakan 'HasColumnType', tentukan presisi dan skala menggunakan 'HasPrecision', atau konfigurasikan pengonversi nilai menggunakan 'HasConversion'.

Di PMC, masukkan perintah berikut:

Update-Database

  • Update-Database: Memperbarui database ke migrasi terbaru, yang dibuat perintah sebelumnya. Perintah ini menjalankan Up metode dalam Migrations/{time-stamp}_InitialCreate.cs file, yang membuat database.

Untuk informasi selengkapnya tentang alat PMC untuk EF Core, lihat EF Core referensi alat - PMC di Visual Studio.

Menguji aplikasi

Jalankan aplikasi dan pilih tautan Aplikasi Film.

Jika Anda mendapatkan pengecualian yang mirip dengan yang berikut ini, Anda mungkin telah melewatkan Update-Database perintah dalam langkah migrasi:

SqlException: Cannot open database "MvcMovieContext-1" requested by the login. The login failed.

Catatan

Anda mungkin tidak dapat memasukkan koma desimal di Price bidang . Untuk mendukung validasi jQuery untuk lokal non-Bahasa Inggris yang menggunakan koma (",") untuk titik desimal dan untuk format tanggal non-Bahasa Inggris AS, aplikasi harus di globalisasi. Untuk instruksi globalisasi, lihat masalah GitHub ini.

Memeriksa kelas konteks database dan pendaftaran yang dihasilkan

Dengan EF Core, akses data dilakukan menggunakan model. Model terdiri dari kelas entitas dan objek konteks yang mewakili sesi dengan database. Objek konteks memungkinkan kueri dan penyimpanan data. Konteks database berasal dari Microsoft.EntityFrameworkCore.DbContext dan menentukan entitas yang akan disertakan dalam model data.

Perancah membuat Data/MvcMovieContext.cs kelas konteks database:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using MvcMovie.Models;

namespace MvcMovie.Data
{
    public class MvcMovieContext : DbContext
    {
        public MvcMovieContext (DbContextOptions<MvcMovieContext> options)
            : base(options)
        {
        }

        public DbSet<MvcMovie.Models.Movie> Movie { get; set; } = default!;
    }
}

Kode sebelumnya membuat properti DbSet<Movie> yang mewakili film dalam database.

Injeksi dependensi

ASP.NET Core dibangun dengan injeksi dependensi (DI). Layanan, seperti konteks database, terdaftar dengan DI di Program.cs. Layanan ini disediakan untuk komponen yang mengharuskannya melalui parameter konstruktor.

Controllers/MoviesController.cs Dalam file, konstruktor menggunakan Injeksi Dependensi untuk menyuntikkan MvcMovieContext konteks database ke pengontrol. Konteks database digunakan dalam setiap metode CRUD di pengontrol.

Perancah menghasilkan kode yang disorot berikut di Program.cs:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<MvcMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("MvcMovieContext") ?? throw new InvalidOperationException("Connection string 'MvcMovieContext' not found.")));

Sistem konfigurasi ASP.NET Core membaca string koneksi database "MvcMovieContext".

Memeriksa string koneksi database yang dihasilkan

Perancah menambahkan string koneksi ke appsettings.json file:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "MvcMovieContext": "Server=(localdb)\\mssqllocaldb;Database=MvcMovieContext-4ebefa10-de29-4dea-b2ad-8a8dc6bcf374;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

Untuk pengembangan lokal, sistem konfigurasi ASP.NET Core membaca ConnectionString kunci dari appsettings.json file.

Kelas InitialCreate

Periksa Migrations/{timestamp}_InitialCreate.cs file migrasi:

using System;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace MvcMovie.Migrations
{
    /// <inheritdoc />
    public partial class InitialCreate : Migration
    {
        /// <inheritdoc />
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Movie",
                columns: table => new
                {
                    Id = table.Column<int>(type: "int", nullable: false)
                        .Annotation("SqlServer:Identity", "1, 1"),
                    Title = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    ReleaseDate = table.Column<DateTime>(type: "datetime2", nullable: false),
                    Genre = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Price = table.Column<decimal>(type: "decimal(18,2)", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Movie", x => x.Id);
                });
        }

        /// <inheritdoc />
        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "Movie");
        }
    }
}

Dalam kode sebelumnya:

  • InitialCreate.Up membuat tabel Film dan mengonfigurasi Id sebagai kunci utama.
  • InitialCreate.Down mengembalikan perubahan skema yang Up dibuat oleh migrasi.

Injeksi dependensi di pengontrol

Controllers/MoviesController.cs Buka file dan periksa konstruktor:

public class MoviesController : Controller
{
    private readonly MvcMovieContext _context;

    public MoviesController(MvcMovieContext context)
    {
        _context = context;
    }

Konstruktor menggunakan Injeksi Dependensi untuk menyuntikkan konteks database (MvcMovieContext) ke pengontrol. Konteks database digunakan dalam setiap metode CRUD di pengontrol.

Uji halaman Buat . Masukkan dan kirim data.

Uji halaman Edit, Detail, dan Hapus .

Model yang sangat ditik dan direktif @model

Sebelumnya dalam tutorial ini, Anda melihat bagaimana pengontrol dapat meneruskan data atau objek ke tampilan menggunakan ViewData kamus. ViewData Kamus adalah objek dinamis yang menyediakan cara terikat terlambat yang nyaman untuk meneruskan informasi ke tampilan.

MVC menyediakan kemampuan untuk meneruskan objek model yang ditik dengan kuat ke tampilan. Pendekatan yang sangat ditik ini memungkinkan pemeriksaan kode waktu kompilasi. Mekanisme perancah melewati model yang ditik dengan kuat di MoviesController kelas dan tampilan.

Periksa metode yang dihasilkan Details dalam Controllers/MoviesController.cs file:

// GET: Movies/Details/5
public async Task<IActionResult> Details(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie
        .FirstOrDefaultAsync(m => m.Id == id);
    if (movie == null)
    {
        return NotFound();
    }

    return View(movie);
}

Parameter id umumnya diteruskan sebagai data rute. Misalnya, https://localhost:5001/movies/details/1 set:

  • Pengontrol ke movies pengontrol, segmen URL pertama.
  • Tindakan untuk details, segmen URL kedua.
  • Ke id 1, segmen URL terakhir.

id dapat diteruskan dengan string kueri, seperti dalam contoh berikut:

https://localhost:5001/movies/details?id=1

Parameter id didefinisikan sebagai jenis nullable (int?) dalam kasus ketika id nilai tidak disediakan.

Ekspresi lambda diteruskan ke FirstOrDefaultAsync metode untuk memilih entitas film yang cocok dengan data rute atau nilai string kueri.

var movie = await _context.Movie
    .FirstOrDefaultAsync(m => m.Id == id);

Jika film ditemukan, instans Movie model diteruskan ke Details tampilan:

return View(movie);

Periksa isi Views/Movies/Details.cshtml file:

@model MvcMovie.Models.Movie

@{
    ViewData["Title"] = "Details";
}

<h1>Details</h1>

<div>
    <h4>Movie</h4>
    <hr />
    <dl class="row">
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Title)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Title)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.ReleaseDate)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.ReleaseDate)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Genre)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Genre)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Price)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Price)
        </dd>
    </dl>
</div>
<div>
    <a asp-action="Edit" asp-route-id="@Model.Id">Edit</a> |
    <a asp-action="Index">Back to List</a>
</div>

Pernyataan @model di bagian atas file tampilan menentukan jenis objek yang diharapkan tampilan. Ketika pengontrol film dibuat, pernyataan berikut @model disertakan:

@model MvcMovie.Models.Movie

Arahan ini @model memungkinkan akses ke film yang diteruskan pengontrol ke tampilan. Objek Model dititik dengan kuat. Misalnya, dalam Details.cshtml tampilan, kode meneruskan setiap bidang film ke pembantu DisplayNameFor HTML dan DisplayFor dengan objek yang di ketik Model dengan kuat. Metode Create dan Edit dan tampilan juga meneruskan Movie objek model.

Index.cshtml Periksa tampilan dan Index metode di pengontrol Film. Perhatikan bagaimana kode membuat List objek saat memanggil View metode . Kode meneruskan daftar ini Movies dari Index metode tindakan ke tampilan:

// GET: Movies
public async Task<IActionResult> Index()
{
    return View(await _context.Movie.ToListAsync());
}

Kode mengembalikan detail masalah jika Movie properti konteks data null.

Ketika pengontrol film dibuat, perancah menyertakan pernyataan berikut @model di bagian Index.cshtml atas file:

@model IEnumerable<MvcMovie.Models.Movie>

Direktif @model memungkinkan akses ke daftar film yang diteruskan pengontrol ke tampilan dengan menggunakan Model objek yang sangat diketik. Misalnya, dalam Index.cshtml tampilan, kode mengulang melalui film dengan pernyataan di atas objek yang foreach sangat di ketik Model :

@model IEnumerable<MvcMovie.Models.Movie>

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Model Karena objek sangat ditik sebagai IEnumerable<Movie> objek, setiap item dalam perulangan di ketik sebagai Movie. Di antara manfaat lainnya, kompilator memvalidasi jenis yang digunakan dalam kode.

Sumber Daya Tambahan:

Dalam tutorial ini, kelas ditambahkan untuk mengelola film dalam database. Kelas-kelas ini adalah bagian "Model" dari aplikasi MVC.

Kelas model ini digunakan dengan Entity Framework Core (EF Core) untuk bekerja dengan database. EF Core adalah kerangka kerja pemetaan relasional objek (ORM) yang menyederhanakan kode akses data yang harus Anda tulis.

Kelas model yang dibuat dikenal sebagai kelas POCO, dari Plain Old CLR Objects. Kelas POCO tidak memiliki dependensi pada EF Core. Mereka hanya menentukan properti data yang akan disimpan dalam database.

Dalam tutorial ini, kelas model dibuat terlebih dahulu, dan EF Core membuat database.

Menambahkan kelas model data

Klik kanan folder >Model Tambahkan>Kelas. Beri nama file Movie.cs.

Models/Movie.cs Perbarui file dengan kode berikut:

using System.ComponentModel.DataAnnotations;

namespace MvcMovie.Models;

public class Movie
{
    public int Id { get; set; }
    public string? Title { get; set; }
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }
    public string? Genre { get; set; }
    public decimal Price { get; set; }
}

Kelas Movie berisi Id bidang, yang diperlukan oleh database untuk kunci utama.

Atribut DataType pada ReleaseDate menentukan jenis data (Date). Dengan atribut ini:

  • Pengguna tidak diharuskan memasukkan informasi waktu di bidang tanggal.
  • Hanya tanggal yang ditampilkan, bukan informasi waktu.

DataAnnotations dibahas dalam tutorial selanjutnya.

Tanda tanya setelah string menunjukkan bahwa properti dapat diubah ke null. Untuk informasi selengkapnya, lihat Jenis nilai yang dapat diubah ke null.

Menambahkan paket NuGet

Visual Studio secara otomatis menginstal paket yang diperlukan.

Buat proyek sebagai pemeriksaan kesalahan pengkompilasi.

Halaman film Perancah

Gunakan alat perancah untuk menghasilkan Createhalaman , , ReadUpdate, dan Delete (CRUD) untuk model film.

Di Penjelajah Solusi, klik kanan folder Pengontrol dan pilih Tambahkan > Item Perancah Baru.

tampilan langkah di atas

Dalam dialog Tambahkan Item Perancah Baru:

  • Di panel kiri, pilih Instal MVC Umum.>>
  • Pilih Pengontrol MVC dengan tampilan, menggunakan Kerangka Kerja Entitas.
  • Pilih Tambahkan.

Tambahkan dialog Perancah

Selesaikan dialog Tambahkan Pengontrol MVC dengan tampilan, menggunakan Kerangka Kerja Entitas:

  • Di menu drop-down Kelas model , pilih Film (MvcMovie.Models).
  • Di baris Kelas konteks data, pilih + tanda (plus).
    • Dalam dialog Tambahkan Konteks Data, nama kelas MvcMovie.Data.MvcMovieContext dihasilkan.
    • Pilih Tambahkan.
  • Di menu drop-down Penyedia database, pilih SQL Server.
  • Tampilan dan Nama pengontrol: Pertahankan default.
  • Pilih Tambahkan.

Menambahkan konteks Data menyimpan default

Jika Anda mendapatkan pesan kesalahan, pilih Tambahkan untuk kedua kalinya untuk mencobanya lagi.

Perancah menambahkan paket berikut:

  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools
  • Microsoft.VisualStudio.Web.CodeGeneration.Design

Perancah membuat hal berikut:

  • Pengontrol film: Controllers/MoviesController.cs
  • Razor lihat file untuk halaman Buat, Hapus, Detail, Edit, dan Indeks : Views/Movies/*.cshtml
  • Kelas konteks database: Data/MvcMovieContext.cs

Perancah memperbarui hal berikut:

  • Menyisipkan referensi paket yang MvcMovie.csproj diperlukan dalam file proyek.
  • Mendaftarkan konteks database dalam Program.cs file.
  • Menambahkan database string koneksi ke appsettings.json file.

Pembuatan otomatis file dan pembaruan file ini dikenal sebagai perancah.

Halaman perancah belum dapat digunakan karena database belum ada. Menjalankan aplikasi dan memilih tautan Aplikasi Film menghasilkan tidak dapat membuka database atau tidak ada tabel seperti itu: Pesan kesalahan film.

Buat aplikasi untuk memverifikasi bahwa tidak ada kesalahan.

Migrasi awal

EF CoreGunakan fitur Migrasi untuk membuat database. Migrasi adalah sekumpulan alat yang membuat dan memperbarui database agar sesuai dengan model data.

Dari menu Alat, pilih Pengelola Paket NuGet>Konsol Pengelola Paket.

Di Package Manager Console (PMC), masukkan perintah berikut:

Add-Migration InitialCreate
Update-Database

  • Add-Migration InitialCreate: Menghasilkan Migrations/{timestamp}_InitialCreate.cs file migrasi. Argumen InitialCreate adalah nama migrasi. Nama apa pun dapat digunakan, tetapi menurut konvensi, nama dipilih yang menjelaskan migrasi. Karena ini adalah migrasi pertama, kelas yang dihasilkan berisi kode untuk membuat skema database. Skema database didasarkan pada model yang ditentukan di MvcMovieContext kelas .

  • Update-Database: Memperbarui database ke migrasi terbaru, yang dibuat perintah sebelumnya. Perintah ini menjalankan Up metode dalam Migrations/{time-stamp}_InitialCreate.cs file, yang membuat database.

Perintah Update-Database menghasilkan peringatan berikut:

Tidak ada jenis penyimpanan yang ditentukan untuk properti desimal 'Harga' pada jenis entitas 'Film'. Ini akan menyebabkan nilai terpotong secara diam-diam jika tidak cocok dalam presisi dan skala default. Tentukan jenis kolom server SQL secara eksplisit yang dapat mengakomodasi semua nilai di 'OnModelCreating' menggunakan 'HasColumnType', tentukan presisi dan skala menggunakan 'HasPrecision', atau konfigurasikan pengonversi nilai menggunakan 'HasConversion'.

Abaikan peringatan sebelumnya, ini diperbaiki dalam tutorial selanjutnya.

Untuk informasi selengkapnya tentang alat PMC untuk EF Core, lihat EF Core referensi alat - PMC di Visual Studio.

Menguji aplikasi

Jalankan aplikasi dan pilih tautan Aplikasi Film.

Jika Anda mendapatkan pengecualian yang mirip dengan yang berikut ini, Anda mungkin telah melewatkan Update-Database perintah dalam langkah migrasi:

SqlException: Cannot open database "MvcMovieContext-1" requested by the login. The login failed.

Catatan

Anda mungkin tidak dapat memasukkan koma desimal di Price bidang . Untuk mendukung validasi jQuery untuk lokal non-Bahasa Inggris yang menggunakan koma (",") untuk titik desimal dan untuk format tanggal non-Bahasa Inggris AS, aplikasi harus di globalisasi. Untuk instruksi globalisasi, lihat masalah GitHub ini.

Memeriksa kelas konteks database dan pendaftaran yang dihasilkan

Dengan EF Core, akses data dilakukan menggunakan model. Model terdiri dari kelas entitas dan objek konteks yang mewakili sesi dengan database. Objek konteks memungkinkan kueri dan penyimpanan data. Konteks database berasal dari Microsoft.EntityFrameworkCore.DbContext dan menentukan entitas yang akan disertakan dalam model data.

Perancah membuat Data/MvcMovieContext.cs kelas konteks database:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using MvcMovie.Models;

namespace MvcMovie.Data
{
    public class MvcMovieContext : DbContext
    {
        public MvcMovieContext (DbContextOptions<MvcMovieContext> options)
            : base(options)
        {
        }

        public DbSet<MvcMovie.Models.Movie> Movie { get; set; }
    }
}

Kode sebelumnya membuat properti DbSet<Movie> yang mewakili film dalam database.

Injeksi dependensi

ASP.NET Core dibangun dengan injeksi dependensi (DI). Layanan, seperti konteks database, terdaftar dengan DI di Program.cs. Layanan ini disediakan untuk komponen yang mengharuskannya melalui parameter konstruktor.

Controllers/MoviesController.cs Dalam file, konstruktor menggunakan Injeksi Dependensi untuk menyuntikkan MvcMovieContext konteks database ke pengontrol. Konteks database digunakan dalam setiap metode CRUD di pengontrol.

Perancah menghasilkan kode yang disorot berikut di Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<MvcMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("MvcMovieContext")));

Sistem konfigurasi ASP.NET Core membaca string koneksi database "MvcMovieContext".

Memeriksa string koneksi database yang dihasilkan

Perancah menambahkan string koneksi ke appsettings.json file:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "MvcMovieContext": "Data Source=MvcMovieContext-ea7a4069-f366-4742-bd1c-3f753a804ce1.db"
  }
}

Untuk pengembangan lokal, sistem konfigurasi ASP.NET Core membaca ConnectionString kunci dari appsettings.json file.

Kelas InitialCreate

Periksa Migrations/{timestamp}_InitialCreate.cs file migrasi:

using System;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace MvcMovie.Migrations
{
    public partial class InitialCreate : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Movie",
                columns: table => new
                {
                    Id = table.Column<int>(type: "int", nullable: false)
                        .Annotation("SqlServer:Identity", "1, 1"),
                    Title = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    ReleaseDate = table.Column<DateTime>(type: "datetime2", nullable: false),
                    Genre = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Price = table.Column<decimal>(type: "decimal(18,2)", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Movie", x => x.Id);
                });
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "Movie");
        }
    }
}

Dalam kode sebelumnya:

  • InitialCreate.Up membuat tabel Film dan mengonfigurasi Id sebagai kunci utama.
  • InitialCreate.Down mengembalikan perubahan skema yang Up dibuat oleh migrasi.

Injeksi dependensi di pengontrol

Controllers/MoviesController.cs Buka file dan periksa konstruktor:

public class MoviesController : Controller
{
    private readonly MvcMovieContext _context;

    public MoviesController(MvcMovieContext context)
    {
        _context = context;
    }

Konstruktor menggunakan Injeksi Dependensi untuk menyuntikkan konteks database (MvcMovieContext) ke pengontrol. Konteks database digunakan dalam setiap metode CRUD di pengontrol.

Uji halaman Buat . Masukkan dan kirim data.

Uji halaman Edit, Detail, dan Hapus .

Model yang sangat ditik dan direktif @model

Sebelumnya dalam tutorial ini, Anda melihat bagaimana pengontrol dapat meneruskan data atau objek ke tampilan menggunakan ViewData kamus. ViewData Kamus adalah objek dinamis yang menyediakan cara terikat terlambat yang nyaman untuk meneruskan informasi ke tampilan.

MVC menyediakan kemampuan untuk meneruskan objek model yang ditik dengan kuat ke tampilan. Pendekatan yang sangat ditik ini memungkinkan pemeriksaan kode waktu kompilasi. Mekanisme perancah melewati model yang ditik dengan kuat di MoviesController kelas dan tampilan.

Periksa metode yang dihasilkan Details dalam Controllers/MoviesController.cs file:

// GET: Movies/Details/5
public async Task<IActionResult> Details(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie
        .FirstOrDefaultAsync(m => m.Id == id);
    if (movie == null)
    {
        return NotFound();
    }

    return View(movie);
}

Parameter id umumnya diteruskan sebagai data rute. Misalnya, https://localhost:5001/movies/details/1 set:

  • Pengontrol ke movies pengontrol, segmen URL pertama.
  • Tindakan untuk details, segmen URL kedua.
  • Ke id 1, segmen URL terakhir.

id dapat diteruskan dengan string kueri, seperti dalam contoh berikut:

https://localhost:5001/movies/details?id=1

Parameter id didefinisikan sebagai jenis nullable (int?) dalam kasus ketika id nilai tidak disediakan.

Ekspresi lambda diteruskan ke FirstOrDefaultAsync metode untuk memilih entitas film yang cocok dengan data rute atau nilai string kueri.

var movie = await _context.Movie
    .FirstOrDefaultAsync(m => m.Id == id);

Jika film ditemukan, instans Movie model diteruskan ke Details tampilan:

return View(movie);

Periksa isi Views/Movies/Details.cshtml file:

@model MvcMovie.Models.Movie

@{
    ViewData["Title"] = "Details";
}

<h1>Details</h1>

<div>
    <h4>Movie</h4>
    <hr />
    <dl class="row">
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Title)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Title)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.ReleaseDate)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.ReleaseDate)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Genre)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Genre)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Price)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Price)
        </dd>
    </dl>
</div>
<div>
    <a asp-action="Edit" asp-route-id="@Model.Id">Edit</a> |
    <a asp-action="Index">Back to List</a>
</div>

Pernyataan @model di bagian atas file tampilan menentukan jenis objek yang diharapkan tampilan. Ketika pengontrol film dibuat, pernyataan berikut @model disertakan:

@model MvcMovie.Models.Movie

Arahan ini @model memungkinkan akses ke film yang diteruskan pengontrol ke tampilan. Objek Model dititik dengan kuat. Misalnya, dalam Details.cshtml tampilan, kode meneruskan setiap bidang film ke pembantu DisplayNameFor HTML dan DisplayFor dengan objek yang di ketik Model dengan kuat. Metode Create dan Edit dan tampilan juga meneruskan Movie objek model.

Index.cshtml Periksa tampilan dan Index metode di pengontrol Film. Perhatikan bagaimana kode membuat List objek saat memanggil View metode . Kode meneruskan daftar ini Movies dari Index metode tindakan ke tampilan:

// GET: Movies
public async Task<IActionResult> Index()
{
    return View(await _context.Movie.ToListAsync());
}

Kode mengembalikan detail masalah jika Movie properti konteks data null.

Ketika pengontrol film dibuat, perancah menyertakan pernyataan berikut @model di bagian Index.cshtml atas file:

@model IEnumerable<MvcMovie.Models.Movie>

Direktif @model memungkinkan akses ke daftar film yang diteruskan pengontrol ke tampilan dengan menggunakan Model objek yang sangat diketik. Misalnya, dalam Index.cshtml tampilan, kode mengulang melalui film dengan pernyataan di atas objek yang foreach sangat di ketik Model :

@model IEnumerable<MvcMovie.Models.Movie>

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Model Karena objek sangat ditik sebagai IEnumerable<Movie> objek, setiap item dalam perulangan di ketik sebagai Movie. Di antara manfaat lainnya, kompilator memvalidasi jenis yang digunakan dalam kode.

Sumber Daya Tambahan:

Dalam tutorial ini, kelas ditambahkan untuk mengelola film dalam database. Kelas-kelas ini adalah bagian "Model" dari aplikasi MVC.

Kelas model ini digunakan dengan Entity Framework Core (EF Core) untuk bekerja dengan database. EF Core adalah kerangka kerja pemetaan relasional objek (ORM) yang menyederhanakan kode akses data yang harus Anda tulis.

Kelas model yang dibuat dikenal sebagai kelas POCO, dari Plain Old CLR Objects. Kelas POCO tidak memiliki dependensi pada EF Core. Mereka hanya menentukan properti data yang akan disimpan dalam database.

Dalam tutorial ini, kelas model dibuat terlebih dahulu, dan EF Core membuat database.

Menambahkan kelas model data

Klik kanan folder >Model Tambahkan>Kelas. Beri nama file Movie.cs.

Models/Movie.cs Perbarui file dengan kode berikut:

using System.ComponentModel.DataAnnotations;

namespace MvcMovie.Models;

public class Movie
{
    public int Id { get; set; }
    public string? Title { get; set; }
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }
    public string? Genre { get; set; }
    public decimal Price { get; set; }
}

Kelas Movie berisi Id bidang, yang diperlukan oleh database untuk kunci utama.

Atribut DataType pada ReleaseDate menentukan jenis data (Date). Dengan atribut ini:

  • Pengguna tidak diharuskan memasukkan informasi waktu di bidang tanggal.
  • Hanya tanggal yang ditampilkan, bukan informasi waktu.

DataAnnotations dibahas dalam tutorial selanjutnya.

Tanda tanya setelah string menunjukkan bahwa properti dapat diubah ke null. Untuk informasi selengkapnya, lihat Jenis nilai yang dapat diubah ke null.

Menambahkan paket NuGet

Visual Studio secara otomatis menginstal paket yang diperlukan.

Buat proyek sebagai pemeriksaan kesalahan pengkompilasi.

Halaman film Perancah

Gunakan alat perancah untuk menghasilkan Createhalaman , , ReadUpdate, dan Delete (CRUD) untuk model film.

Di Penjelajah Solusi, klik kanan folder Pengontrol dan pilih Tambahkan > Item Perancah Baru.

tampilan langkah di atas

Dalam dialog Tambahkan Item Perancah Baru:

  • Di panel kiri, pilih Instal MVC Umum.>>
  • Pilih Pengontrol MVC dengan tampilan, menggunakan Kerangka Kerja Entitas.
  • Pilih Tambahkan.

Tambahkan dialog Perancah

Selesaikan dialog Tambahkan Pengontrol MVC dengan tampilan, menggunakan Kerangka Kerja Entitas:

  • Di menu drop-down Kelas model , pilih Film (MvcMovie.Models).
  • Di baris Kelas konteks data, pilih + tanda (plus).
    • Dalam dialog Tambahkan Konteks Data, nama kelas MvcMovie.Data.MvcMovieContext dihasilkan.
    • Pilih Tambahkan.
  • Di menu drop-down Penyedia database, pilih SQL Server.
  • Tampilan dan Nama pengontrol: Pertahankan default.
  • Pilih Tambahkan.

Menambahkan konteks Data menyimpan default Jika Anda mendapatkan pesan kesalahan, pilih Tambahkan untuk kedua kalinya untuk mencobanya lagi.

Perancah menambahkan paket berikut:

  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools
  • Microsoft.VisualStudio.Web.CodeGeneration.Design

Perancah membuat hal berikut:

  • Pengontrol film: Controllers/MoviesController.cs
  • Razor lihat file untuk halaman Buat, Hapus, Detail, Edit, dan Indeks : Views/Movies/*.cshtml
  • Kelas konteks database: Data/MvcMovieContext.cs

Perancah memperbarui hal berikut:

  • Menyisipkan referensi paket yang MvcMovie.csproj diperlukan dalam file proyek.
  • Mendaftarkan konteks database dalam Program.cs file.
  • Menambahkan database string koneksi ke appsettings.json file.

Pembuatan otomatis file dan pembaruan file ini dikenal sebagai perancah.

Halaman perancah belum dapat digunakan karena database belum ada. Menjalankan aplikasi dan memilih tautan Aplikasi Film menghasilkan tidak dapat membuka database atau tidak ada tabel seperti itu: Pesan kesalahan film.

Buat aplikasi untuk memverifikasi bahwa tidak ada kesalahan.

Migrasi awal

EF CoreGunakan fitur Migrasi untuk membuat database. Migrasi adalah sekumpulan alat yang membuat dan memperbarui database agar sesuai dengan model data.

Dari menu Alat, pilih Pengelola Paket NuGet>Konsol Pengelola Paket.

Di Package Manager Console (PMC), masukkan perintah berikut:

Add-Migration InitialCreate
Update-Database

  • Add-Migration InitialCreate: Menghasilkan Migrations/{timestamp}_InitialCreate.cs file migrasi. Argumen InitialCreate adalah nama migrasi. Nama apa pun dapat digunakan, tetapi menurut konvensi, nama dipilih yang menjelaskan migrasi. Karena ini adalah migrasi pertama, kelas yang dihasilkan berisi kode untuk membuat skema database. Skema database didasarkan pada model yang ditentukan di MvcMovieContext kelas .

  • Update-Database: Memperbarui database ke migrasi terbaru, yang dibuat perintah sebelumnya. Perintah ini menjalankan Up metode dalam Migrations/{time-stamp}_InitialCreate.cs file, yang membuat database.

Perintah Update-Database menghasilkan peringatan berikut:

Tidak ada jenis yang ditentukan untuk kolom desimal 'Harga' pada jenis entitas 'Film'. Ini akan menyebabkan nilai terpotong secara diam-diam jika tidak cocok dalam presisi dan skala default. Tentukan jenis kolom server SQL secara eksplisit yang dapat mengakomodasi semua nilai menggunakan 'HasColumnType()'.

Abaikan peringatan sebelumnya, ini diperbaiki dalam tutorial selanjutnya.

Untuk informasi selengkapnya tentang alat PMC untuk EF Core, lihat EF Core referensi alat - PMC di Visual Studio.

Menguji aplikasi

Jalankan aplikasi dan pilih tautan Aplikasi Film.

Jika Anda mendapatkan pengecualian yang mirip dengan yang berikut ini, Anda mungkin telah melewatkan Update-Database perintah dalam langkah migrasi:

SqlException: Cannot open database "MvcMovieContext-1" requested by the login. The login failed.

Catatan

Anda mungkin tidak dapat memasukkan koma desimal di Price bidang . Untuk mendukung validasi jQuery untuk lokal non-Bahasa Inggris yang menggunakan koma (",") untuk titik desimal dan untuk format tanggal non-Bahasa Inggris AS, aplikasi harus di globalisasi. Untuk instruksi globalisasi, lihat masalah GitHub ini.

Memeriksa kelas konteks database dan pendaftaran yang dihasilkan

Dengan EF Core, akses data dilakukan menggunakan model. Model terdiri dari kelas entitas dan objek konteks yang mewakili sesi dengan database. Objek konteks memungkinkan kueri dan penyimpanan data. Konteks database berasal dari Microsoft.EntityFrameworkCore.DbContext dan menentukan entitas yang akan disertakan dalam model data.

Perancah membuat Data/MvcMovieContext.cs kelas konteks database:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using MvcMovie.Models;

namespace MvcMovie.Data
{
    public class MvcMovieContext : DbContext
    {
        public MvcMovieContext (DbContextOptions<MvcMovieContext> options)
            : base(options)
        {
        }

        public DbSet<MvcMovie.Models.Movie> Movie { get; set; }
    }
}

Kode sebelumnya membuat properti DbSet<Movie> yang mewakili film dalam database.

Injeksi dependensi

ASP.NET Core dibangun dengan injeksi dependensi (DI). Layanan, seperti konteks database, terdaftar dengan DI di Program.cs. Layanan ini disediakan untuk komponen yang mengharuskannya melalui parameter konstruktor.

Controllers/MoviesController.cs Dalam file, konstruktor menggunakan Injeksi Dependensi untuk menyuntikkan MvcMovieContext konteks database ke pengontrol. Konteks database digunakan dalam setiap metode CRUD di pengontrol.

Perancah menghasilkan kode yang disorot berikut di Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<MvcMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("MvcMovieContext")));

Sistem konfigurasi ASP.NET Core membaca string koneksi database "MvcMovieContext".

Memeriksa string koneksi database yang dihasilkan

Perancah menambahkan string koneksi ke appsettings.json file:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "MvcMovieContext": "Data Source=MvcMovieContext-ea7a4069-f366-4742-bd1c-3f753a804ce1.db"
  }
}

Untuk pengembangan lokal, sistem konfigurasi ASP.NET Core membaca ConnectionString kunci dari appsettings.json file.

Kelas InitialCreate

Periksa Migrations/{timestamp}_InitialCreate.cs file migrasi:

using System;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace MvcMovie.Migrations
{
    public partial class InitialCreate : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Movie",
                columns: table => new
                {
                    Id = table.Column<int>(type: "int", nullable: false)
                        .Annotation("SqlServer:Identity", "1, 1"),
                    Title = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    ReleaseDate = table.Column<DateTime>(type: "datetime2", nullable: false),
                    Genre = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Price = table.Column<decimal>(type: "decimal(18,2)", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Movie", x => x.Id);
                });
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "Movie");
        }
    }
}

Dalam kode sebelumnya:

  • InitialCreate.Up membuat tabel Film dan mengonfigurasi Id sebagai kunci utama.
  • InitialCreate.Down mengembalikan perubahan skema yang Up dibuat oleh migrasi.

Injeksi dependensi di pengontrol

Controllers/MoviesController.cs Buka file dan periksa konstruktor:

public class MoviesController : Controller
{
    private readonly MvcMovieContext _context;

    public MoviesController(MvcMovieContext context)
    {
        _context = context;
    }

Konstruktor menggunakan Injeksi Dependensi untuk menyuntikkan konteks database (MvcMovieContext) ke pengontrol. Konteks database digunakan dalam setiap metode CRUD di pengontrol.

Uji halaman Buat . Masukkan dan kirim data.

Uji halaman Edit, Detail, dan Hapus .

Model yang sangat ditik dan direktif @model

Sebelumnya dalam tutorial ini, Anda melihat bagaimana pengontrol dapat meneruskan data atau objek ke tampilan menggunakan ViewData kamus. ViewData Kamus adalah objek dinamis yang menyediakan cara terikat terlambat yang nyaman untuk meneruskan informasi ke tampilan.

MVC menyediakan kemampuan untuk meneruskan objek model yang ditik dengan kuat ke tampilan. Pendekatan yang sangat ditik ini memungkinkan pemeriksaan kode waktu kompilasi. Mekanisme perancah melewati model yang ditik dengan kuat di MoviesController kelas dan tampilan.

Periksa metode yang dihasilkan Details dalam Controllers/MoviesController.cs file:

// GET: Movies/Details/5
public async Task<IActionResult> Details(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie
        .FirstOrDefaultAsync(m => m.Id == id);
    if (movie == null)
    {
        return NotFound();
    }

    return View(movie);
}

Parameter id umumnya diteruskan sebagai data rute. Misalnya, https://localhost:5001/movies/details/1 set:

  • Pengontrol ke movies pengontrol, segmen URL pertama.
  • Tindakan untuk details, segmen URL kedua.
  • Ke id 1, segmen URL terakhir.

id dapat diteruskan dengan string kueri, seperti dalam contoh berikut:

https://localhost:5001/movies/details?id=1

Parameter id didefinisikan sebagai jenis nullable (int?) dalam kasus ketika id nilai tidak disediakan.

Ekspresi lambda diteruskan ke FirstOrDefaultAsync metode untuk memilih entitas film yang cocok dengan data rute atau nilai string kueri.

var movie = await _context.Movie
    .FirstOrDefaultAsync(m => m.Id == id);

Jika film ditemukan, instans Movie model diteruskan ke Details tampilan:

return View(movie);

Periksa isi Views/Movies/Details.cshtml file:

@model MvcMovie.Models.Movie

@{
    ViewData["Title"] = "Details";
}

<h1>Details</h1>

<div>
    <h4>Movie</h4>
    <hr />
    <dl class="row">
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Title)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Title)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.ReleaseDate)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.ReleaseDate)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Genre)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Genre)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Price)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Price)
        </dd>
    </dl>
</div>
<div>
    <a asp-action="Edit" asp-route-id="@Model.Id">Edit</a> |
    <a asp-action="Index">Back to List</a>
</div>

Pernyataan @model di bagian atas file tampilan menentukan jenis objek yang diharapkan tampilan. Ketika pengontrol film dibuat, pernyataan berikut @model disertakan:

@model MvcMovie.Models.Movie

Arahan ini @model memungkinkan akses ke film yang diteruskan pengontrol ke tampilan. Objek Model dititik dengan kuat. Misalnya, dalam Details.cshtml tampilan, kode meneruskan setiap bidang film ke pembantu DisplayNameFor HTML dan DisplayFor dengan objek yang di ketik Model dengan kuat. Metode Create dan Edit dan tampilan juga meneruskan Movie objek model.

Index.cshtml Periksa tampilan dan Index metode di pengontrol Film. Perhatikan bagaimana kode membuat List objek saat memanggil View metode . Kode meneruskan daftar ini Movies dari Index metode tindakan ke tampilan:

// GET: Movies
public async Task<IActionResult> Index()
{
    return View(await _context.Movie.ToListAsync());
}

Kode mengembalikan detail masalah jika Movie properti konteks data null.

Ketika pengontrol film dibuat, perancah menyertakan pernyataan berikut @model di bagian Index.cshtml atas file:

@model IEnumerable<MvcMovie.Models.Movie>

Direktif @model memungkinkan akses ke daftar film yang diteruskan pengontrol ke tampilan dengan menggunakan Model objek yang sangat diketik. Misalnya, dalam Index.cshtml tampilan, kode mengulang melalui film dengan pernyataan di atas objek yang foreach sangat di ketik Model :

@model IEnumerable<MvcMovie.Models.Movie>

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Model Karena objek sangat ditik sebagai IEnumerable<Movie> objek, setiap item dalam perulangan di ketik sebagai Movie. Di antara manfaat lainnya, kompilator memvalidasi jenis yang digunakan dalam kode.

Sumber Daya Tambahan:

Dalam tutorial ini, kelas ditambahkan untuk mengelola film dalam database. Kelas-kelas ini adalah bagian "Model" dari aplikasi MVC.

Kelas model ini digunakan dengan Entity Framework Core (EF Core) untuk bekerja dengan database. EF Core adalah kerangka kerja pemetaan relasional objek (ORM) yang menyederhanakan kode akses data yang harus Anda tulis.

Kelas model yang dibuat dikenal sebagai kelas POCO, dari Plain Old CLR Objects. Kelas POCO tidak memiliki dependensi pada EF Core. Mereka hanya menentukan properti data yang akan disimpan dalam database.

Dalam tutorial ini, kelas model dibuat terlebih dahulu, dan EF Core membuat database.

Menambahkan kelas model data

Klik kanan folder >Model Tambahkan>Kelas. Beri nama file Movie.cs.

Models/Movie.cs Perbarui file dengan kode berikut:

using System.ComponentModel.DataAnnotations;

namespace MvcMovie.Models
{
    public class Movie
    {
        public int Id { get; set; }
        public string? Title { get; set; }

        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string? Genre { get; set; }
        public decimal Price { get; set; }
    }
}

Kelas Movie berisi Id bidang, yang diperlukan oleh database untuk kunci utama.

Atribut DataType pada ReleaseDate menentukan jenis data (Date). Dengan atribut ini:

  • Pengguna tidak diharuskan memasukkan informasi waktu di bidang tanggal.
  • Hanya tanggal yang ditampilkan, bukan informasi waktu.

DataAnnotations dibahas dalam tutorial selanjutnya.

Tanda tanya setelah string menunjukkan bahwa properti dapat diubah ke null. Untuk informasi selengkapnya, lihat Jenis nilai yang dapat diubah ke null.

Menambahkan paket NuGet

Dari menu Alat, pilih NuGet Package Manager>Package Manager Console (PMC).

Menu PMC

Di PMC, jalankan perintah berikut:

Install-Package Microsoft.EntityFrameworkCore.Design
Install-Package Microsoft.EntityFrameworkCore.SqlServer

Perintah sebelumnya menambahkan:

  • Penyedia EF Core SQL Server. Paket penyedia menginstal EF Core paket sebagai dependensi.
  • Utilitas yang digunakan oleh paket yang diinstal secara otomatis dalam langkah perancah, nanti dalam tutorial.

Buat proyek sebagai pemeriksaan kesalahan pengkompilasi.

Halaman film Perancah

Gunakan alat perancah untuk menghasilkan Createhalaman , , ReadUpdate, dan Delete (CRUD) untuk model film.

Di Penjelajah Solusi, klik kanan folder Pengontrol dan pilih Tambahkan > Item Perancah Baru.

tampilan langkah di atas

Dalam dialog Tambahkan Perancah, pilih Pengontrol MVC dengan tampilan, menggunakan Tambahkan Kerangka Kerja > Entitas.

Tambahkan dialog Perancah

Selesaikan dialog Tambahkan Pengontrol MVC dengan tampilan, menggunakan Kerangka Kerja Entitas:

  • Di menu drop-down Kelas model , pilih Film (MvcMovie.Models).
  • Di baris Kelas konteks data, pilih + tanda (plus).
    • Dalam dialog Tambahkan Konteks Data, nama kelas MvcMovie.Data.MvcMovieContext dihasilkan.
    • Pilih Tambahkan.
  • Tampilan dan Nama pengontrol: Pertahankan default.
  • Pilih Tambahkan.

Menambahkan konteks Data menyimpan default

Jika Anda mendapatkan pesan kesalahan, pilih Tambahkan untuk kedua kalinya untuk mencobanya lagi.

Perancah memperbarui hal berikut:

  • Menyisipkan referensi paket yang MvcMovie.csproj diperlukan dalam file proyek.
  • Mendaftarkan konteks database dalam Program.cs file.
  • Menambahkan database string koneksi ke appsettings.json file.

Perancah membuat hal berikut:

  • Pengontrol film: Controllers/MoviesController.cs
  • Razor lihat file untuk halaman Buat, Hapus, Detail, Edit, dan Indeks : Views/Movies/*.cshtml
  • Kelas konteks database: Data/MvcMovieContext.cs

Pembuatan otomatis file dan pembaruan file ini dikenal sebagai perancah.

Halaman perancah belum dapat digunakan karena database belum ada. Menjalankan aplikasi dan memilih tautan Aplikasi Film menghasilkan tidak dapat membuka database atau tidak ada tabel seperti itu: Pesan kesalahan film.

Membangun aplikasi

Buat aplikasi. Pengkompilasi menghasilkan beberapa peringatan tentang bagaimana null nilai ditangani. Lihat masalah GitHub ini dan Jenis referensi nullable untuk informasi selengkapnya.

Untuk menghilangkan peringatan dari jenis referensi yang dapat diubah ke null, hapus baris berikut dari MvcMovie.csproj file:

<Nullable>enable</Nullable>

Kami berharap dapat memperbaiki masalah ini di rilis berikutnya.

Migrasi awal

EF CoreGunakan fitur Migrasi untuk membuat database. Migrasi adalah sekumpulan alat yang membuat dan memperbarui database agar sesuai dengan model data.

Dari menu Alat, pilih Pengelola Paket NuGet>Konsol Pengelola Paket.

Di Package Manager Console (PMC), masukkan perintah berikut:

Add-Migration InitialCreate
Update-Database

  • Add-Migration InitialCreate: Menghasilkan Migrations/{timestamp}_InitialCreate.cs file migrasi. Argumen InitialCreate adalah nama migrasi. Nama apa pun dapat digunakan, tetapi menurut konvensi, nama dipilih yang menjelaskan migrasi. Karena ini adalah migrasi pertama, kelas yang dihasilkan berisi kode untuk membuat skema database. Skema database didasarkan pada model yang ditentukan di MvcMovieContext kelas .

  • Update-Database: Memperbarui database ke migrasi terbaru, yang dibuat perintah sebelumnya. Perintah ini menjalankan Up metode dalam Migrations/{time-stamp}_InitialCreate.cs file, yang membuat database.

Perintah Update-Database menghasilkan peringatan berikut:

Tidak ada jenis yang ditentukan untuk kolom desimal 'Harga' pada jenis entitas 'Film'. Ini akan menyebabkan nilai terpotong secara diam-diam jika tidak cocok dalam presisi dan skala default. Tentukan jenis kolom server SQL secara eksplisit yang dapat mengakomodasi semua nilai menggunakan 'HasColumnType()'.

Abaikan peringatan sebelumnya, ini diperbaiki dalam tutorial selanjutnya.

Untuk informasi selengkapnya tentang alat PMC untuk EF Core, lihat EF Core referensi alat - PMC di Visual Studio.

Menguji aplikasi

Jalankan aplikasi dan pilih tautan Aplikasi Film.

Jika Anda mendapatkan pengecualian yang mirip dengan yang berikut ini, Anda mungkin telah melewatkan langkah migrasi:

SqlException: Cannot open database "MvcMovieContext-1" requested by the login. The login failed.

Catatan

Anda mungkin tidak dapat memasukkan koma desimal di Price bidang . Untuk mendukung validasi jQuery untuk lokal non-Bahasa Inggris yang menggunakan koma (",") untuk titik desimal dan untuk format tanggal non-Bahasa Inggris AS, aplikasi harus di globalisasi. Untuk instruksi globalisasi, lihat masalah GitHub ini.

Memeriksa kelas konteks database dan pendaftaran yang dihasilkan

Dengan EF Core, akses data dilakukan menggunakan model. Model terdiri dari kelas entitas dan objek konteks yang mewakili sesi dengan database. Objek konteks memungkinkan kueri dan penyimpanan data. Konteks database berasal dari Microsoft.EntityFrameworkCore.DbContext dan menentukan entitas yang akan disertakan dalam model data.

Perancah membuat Data/MvcMovieContext.cs kelas konteks database:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using MvcMovie.Models;

namespace MvcMovie.Data
{
    public class MvcMovieContext : DbContext
    {
        public MvcMovieContext (DbContextOptions<MvcMovieContext> options)
            : base(options)
        {
        }

        public DbSet<MvcMovie.Models.Movie> Movie { get; set; }
    }
}

Kode sebelumnya membuat properti DbSet<Movie> yang mewakili film dalam database.

Injeksi dependensi

ASP.NET Core dibangun dengan injeksi dependensi (DI). Layanan, seperti konteks database, terdaftar dengan DI di Program.cs. Layanan ini disediakan untuk komponen yang mengharuskannya melalui parameter konstruktor.

Controllers/MoviesController.cs Dalam file, konstruktor menggunakan Injeksi Dependensi untuk menyuntikkan MvcMovieContext konteks database ke pengontrol. Konteks database digunakan dalam setiap metode CRUD di pengontrol.

Perancah menghasilkan kode yang disorot berikut di Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<MvcMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("MvcMovieContext")));

Sistem konfigurasi ASP.NET Core membaca string koneksi database "MvcMovieContext".

Memeriksa string koneksi database yang dihasilkan

Perancah menambahkan string koneksi ke appsettings.json file:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "MvcMovieContext": "Server=(localdb)\\mssqllocaldb;Database=MvcMovieContext-7dc5;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

Untuk pengembangan lokal, sistem konfigurasi ASP.NET Core membaca ConnectionString kunci dari appsettings.json file.

Kelas InitialCreate

Periksa Migrations/{timestamp}_InitialCreate.cs file migrasi:

using System;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace MvcMovie.Migrations
{
    public partial class InitialCreate : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Movie",
                columns: table => new
                {
                    Id = table.Column<int>(type: "int", nullable: false)
                        .Annotation("SqlServer:Identity", "1, 1"),
                    Title = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    ReleaseDate = table.Column<DateTime>(type: "datetime2", nullable: false),
                    Genre = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Price = table.Column<decimal>(type: "decimal(18,2)", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Movie", x => x.Id);
                });
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "Movie");
        }
    }
}

Dalam kode sebelumnya:

  • InitialCreate.Up membuat tabel Film dan mengonfigurasi Id sebagai kunci utama.
  • InitialCreate.Down mengembalikan perubahan skema yang Up dibuat oleh migrasi.

Injeksi dependensi di pengontrol

Controllers/MoviesController.cs Buka file dan periksa konstruktor:

public class MoviesController : Controller
{
    private readonly MvcMovieContext _context;

    public MoviesController(MvcMovieContext context)
    {
        _context = context;
    }

Konstruktor menggunakan Injeksi Dependensi untuk menyuntikkan konteks database (MvcMovieContext) ke pengontrol. Konteks database digunakan dalam setiap metode CRUD di pengontrol.

Uji halaman Buat . Masukkan dan kirim data.

Uji halaman Edit, Detail, dan Hapus .

Model yang sangat ditik dan direktif @model

Sebelumnya dalam tutorial ini, Anda melihat bagaimana pengontrol dapat meneruskan data atau objek ke tampilan menggunakan ViewData kamus. ViewData Kamus adalah objek dinamis yang menyediakan cara terikat terlambat yang nyaman untuk meneruskan informasi ke tampilan.

MVC menyediakan kemampuan untuk meneruskan objek model yang ditik dengan kuat ke tampilan. Pendekatan yang sangat ditik ini memungkinkan pemeriksaan kode waktu kompilasi. Mekanisme perancah melewati model yang ditik dengan kuat di MoviesController kelas dan tampilan.

Periksa metode yang dihasilkan Details dalam Controllers/MoviesController.cs file:

// GET: Movies/Details/5
public async Task<IActionResult> Details(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie
        .FirstOrDefaultAsync(m => m.Id == id);
    if (movie == null)
    {
        return NotFound();
    }

    return View(movie);
}

Parameter id umumnya diteruskan sebagai data rute. Misalnya, https://localhost:5001/movies/details/1 set:

  • Pengontrol ke movies pengontrol, segmen URL pertama.
  • Tindakan untuk details, segmen URL kedua.
  • Ke id 1, segmen URL terakhir.

id dapat diteruskan dengan string kueri, seperti dalam contoh berikut:

https://localhost:5001/movies/details?id=1

Parameter id didefinisikan sebagai jenis nullable (int?) dalam kasus ketika id nilai tidak disediakan.

Ekspresi lambda diteruskan ke FirstOrDefaultAsync metode untuk memilih entitas film yang cocok dengan data rute atau nilai string kueri.

var movie = await _context.Movie
    .FirstOrDefaultAsync(m => m.Id == id);

Jika film ditemukan, instans Movie model diteruskan ke Details tampilan:

return View(movie);

Periksa isi Views/Movies/Details.cshtml file:

@model MvcMovie.Models.Movie

@{
    ViewData["Title"] = "Details";
}

<h1>Details</h1>

<div>
    <h4>Movie</h4>
    <hr />
    <dl class="row">
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Title)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Title)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.ReleaseDate)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.ReleaseDate)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Genre)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Genre)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Price)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Price)
        </dd>
    </dl>
</div>
<div>
    <a asp-action="Edit" asp-route-id="@Model.Id">Edit</a> |
    <a asp-action="Index">Back to List</a>
</div>

Pernyataan @model di bagian atas file tampilan menentukan jenis objek yang diharapkan tampilan. Ketika pengontrol film dibuat, pernyataan berikut @model disertakan:

@model MvcMovie.Models.Movie

Arahan ini @model memungkinkan akses ke film yang diteruskan pengontrol ke tampilan. Objek Model dititik dengan kuat. Misalnya, dalam Details.cshtml tampilan, kode meneruskan setiap bidang film ke pembantu DisplayNameFor HTML dan DisplayFor dengan objek yang di ketik Model dengan kuat. Metode Create dan Edit dan tampilan juga meneruskan Movie objek model.

Index.cshtml Periksa tampilan dan Index metode di pengontrol Film. Perhatikan bagaimana kode membuat List objek saat memanggil View metode . Kode meneruskan daftar ini Movies dari Index metode tindakan ke tampilan:

// GET: Movies
public async Task<IActionResult> Index()
{
    return View(await _context.Movie.ToListAsync());
}

Ketika pengontrol film dibuat, perancah menyertakan pernyataan berikut @model di bagian Index.cshtml atas file:

@model IEnumerable<MvcMovie.Models.Movie>

Direktif @model memungkinkan akses ke daftar film yang diteruskan pengontrol ke tampilan dengan menggunakan Model objek yang sangat diketik. Misalnya, dalam Index.cshtml tampilan, kode mengulang melalui film dengan pernyataan di atas objek yang foreach sangat di ketik Model :

@model IEnumerable<MvcMovie.Models.Movie>

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Model Karena objek sangat ditik sebagai IEnumerable<Movie> objek, setiap item dalam perulangan di ketik sebagai Movie. Di antara manfaat lainnya, kompilator memvalidasi jenis yang digunakan dalam kode.

Sumber Daya Tambahan:

Dalam tutorial ini, kelas ditambahkan untuk mengelola film dalam database. Kelas-kelas ini adalah bagian "Model" dari aplikasi MVC.

Kelas model ini digunakan dengan Entity Framework Core (EF Core) untuk bekerja dengan database. EF Core adalah kerangka kerja pemetaan relasional objek (ORM) yang menyederhanakan kode akses data yang harus Anda tulis.

Kelas model yang dibuat dikenal sebagai kelas POCO, dari Plain Old CLR Objects. Kelas POCO tidak memiliki dependensi pada EF Core. Mereka hanya menentukan properti data yang akan disimpan dalam database.

Dalam tutorial ini, kelas model dibuat terlebih dahulu, dan EF Core membuat database.

Menambahkan kelas model data

Klik kanan folder >Model Tambahkan>Kelas. Beri nama file Movie.cs.

Models/Movie.cs Perbarui file dengan kode berikut:

using System;
using System.ComponentModel.DataAnnotations;

namespace MvcMovie.Models
{
    public class Movie
    {
        public int Id { get; set; }
        public string Title { get; set; }

        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; }
        public decimal Price { get; set; }
    }
}

Kelas Movie berisi Id bidang, yang diperlukan oleh database untuk kunci utama.

Atribut DataType pada ReleaseDate menentukan jenis data (Date). Dengan atribut ini:

  • Pengguna tidak diharuskan memasukkan informasi waktu di bidang tanggal.
  • Hanya tanggal yang ditampilkan, bukan informasi waktu.

DataAnnotations dibahas dalam tutorial selanjutnya.

Menambahkan paket NuGet

Dari menu Alat, pilih NuGet Package Manager>Package Manager Console (PMC).

Menu PMC

Di PMC, jalankan perintah berikut:

Install-Package Microsoft.EntityFrameworkCore.Design

Perintah sebelumnya menambahkan:

  • Penyedia EF Core SQL Server. Paket penyedia menginstal EF Core paket sebagai dependensi.
  • Utilitas yang digunakan oleh paket yang diinstal secara otomatis dalam langkah perancah, nanti dalam tutorial.

Buat proyek sebagai pemeriksaan kesalahan pengkompilasi.

Halaman film Perancah

Gunakan alat perancah untuk menghasilkan Createhalaman , , ReadUpdate, dan Delete (CRUD) untuk model film.

Di Penjelajah Solusi, klik kanan folder Pengontrol dan pilih Tambahkan > Item Perancah Baru.

tampilan langkah di atas

Dalam dialog Tambahkan Perancah, pilih Pengontrol MVC dengan tampilan, menggunakan Tambahkan Kerangka Kerja > Entitas.

Tambahkan dialog Perancah

Selesaikan dialog Tambahkan Pengontrol MVC dengan tampilan, menggunakan Kerangka Kerja Entitas:

  • Di menu drop-down Kelas model , pilih Film (MvcMovie.Models).
  • Di baris Kelas konteks data, pilih + tanda (plus).
    • Dalam dialog Tambahkan Konteks Data, nama kelas MvcMovie.Data.MvcMovieContext dihasilkan.
    • Pilih Tambahkan.
  • Tampilan dan Nama pengontrol: Pertahankan default.
  • Pilih Tambahkan.

Menambahkan konteks Data menyimpan default

Perancah memperbarui hal berikut:

  • Menyisipkan referensi paket yang MvcMovie.csproj diperlukan dalam file proyek.
  • Mendaftarkan konteks database dalam Startup.ConfigureServices Startup.cs file.
  • Menambahkan database string koneksi ke appsettings.json file.

Perancah membuat hal berikut:

  • Pengontrol film: Controllers/MoviesController.cs
  • Razor lihat file untuk halaman Buat, Hapus, Detail, Edit, dan Indeks : Views/Movies/*.cshtml
  • Kelas konteks database: Data/MvcMovieContext.cs

Pembuatan otomatis file dan pembaruan file ini dikenal sebagai perancah.

Halaman perancah belum dapat digunakan karena database belum ada. Menjalankan aplikasi dan memilih tautan Aplikasi Film menghasilkan tidak dapat membuka database atau tidak ada tabel seperti itu: Pesan kesalahan film.

Migrasi awal

EF CoreGunakan fitur Migrasi untuk membuat database. Migrasi adalah sekumpulan alat yang membuat dan memperbarui database agar sesuai dengan model data.

Dari menu Alat, pilih Pengelola Paket NuGet>Konsol Pengelola Paket.

Di Package Manager Console (PMC), masukkan perintah berikut:

Add-Migration InitialCreate
Update-Database

  • Add-Migration InitialCreate: Menghasilkan Migrations/{timestamp}_InitialCreate.cs file migrasi. Argumen InitialCreate adalah nama migrasi. Nama apa pun dapat digunakan, tetapi menurut konvensi, nama dipilih yang menjelaskan migrasi. Karena ini adalah migrasi pertama, kelas yang dihasilkan berisi kode untuk membuat skema database. Skema database didasarkan pada model yang ditentukan di MvcMovieContext kelas .

  • Update-Database: Memperbarui database ke migrasi terbaru, yang dibuat perintah sebelumnya. Perintah ini menjalankan Up metode dalam Migrations/{time-stamp}_InitialCreate.cs file, yang membuat database.

Perintah Update-Database menghasilkan peringatan berikut:

Tidak ada jenis yang ditentukan untuk kolom desimal 'Harga' pada jenis entitas 'Film'. Ini akan menyebabkan nilai terpotong secara diam-diam jika tidak cocok dalam presisi dan skala default. Tentukan jenis kolom server SQL secara eksplisit yang dapat mengakomodasi semua nilai menggunakan 'HasColumnType()'.

Abaikan peringatan sebelumnya, ini diperbaiki dalam tutorial selanjutnya.

Untuk informasi selengkapnya tentang alat PMC untuk EF Core, lihat EF Core referensi alat - PMC di Visual Studio.

Menguji aplikasi

Jalankan aplikasi dan pilih tautan Aplikasi Film.

Jika Anda mendapatkan pengecualian yang mirip dengan yang berikut ini, Anda mungkin telah melewatkan langkah migrasi:

SqlException: Cannot open database "MvcMovieContext-1" requested by the login. The login failed.

Catatan

Anda mungkin tidak dapat memasukkan koma desimal di Price bidang . Untuk mendukung validasi jQuery untuk lokal non-Bahasa Inggris yang menggunakan koma (",") untuk titik desimal dan untuk format tanggal non-Bahasa Inggris AS, aplikasi harus di globalisasi. Untuk instruksi globalisasi, lihat masalah GitHub ini.

Memeriksa kelas konteks database dan pendaftaran yang dihasilkan

Dengan EF Core, akses data dilakukan menggunakan model. Model terdiri dari kelas entitas dan objek konteks yang mewakili sesi dengan database. Objek konteks memungkinkan kueri dan penyimpanan data. Konteks database berasal dari Microsoft.EntityFrameworkCore.DbContext dan menentukan entitas yang akan disertakan dalam model data.

Perancah membuat Data/MvcMovieContext.cs kelas konteks database:

using Microsoft.EntityFrameworkCore;
using MvcMovie.Models;

namespace MvcMovie.Data
{
    public class MvcMovieContext : DbContext
    {
        public MvcMovieContext (DbContextOptions<MvcMovieContext> options)
            : base(options)
        {
        }

        public DbSet<Movie> Movie { get; set; }
    }
}

Kode sebelumnya membuat properti DbSet<Movie> yang mewakili film dalam database.

ASP.NET Core dibangun dengan injeksi dependensi (DI). Layanan, seperti konteks database, harus terdaftar di DI di Startup. Komponen yang memerlukan layanan ini disediakan melalui parameter konstruktor.

Controllers/MoviesController.cs Dalam file, konstruktor menggunakan Injeksi Dependensi untuk menyuntikkan MvcMovieContext konteks database ke pengontrol. Konteks database digunakan dalam setiap metode CRUD di pengontrol.

Perancah menghasilkan kode yang disorot berikut di Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();

    services.AddDbContext<MvcMovieContext>(options =>
    options.UseSqlServer(Configuration.GetConnectionString("MvcMovieContext")));
}

Sistem konfigurasi ASP.NET Core membaca string koneksi database "MvcMovieContext".

Memeriksa string koneksi database yang dihasilkan

Perancah menambahkan string koneksi ke appsettings.json file:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "MvcMovieContext": "Server=(localdb)\\mssqllocaldb;Database=MvcMovieContext-1;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

Untuk pengembangan lokal, sistem konfigurasi ASP.NET Core membaca ConnectionString kunci dari appsettings.json file.

Kelas InitialCreate

Periksa Migrations/{timestamp}_InitialCreate.cs file migrasi:

public partial class InitialCreate : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(
            name: "Movie",
            columns: table => new
            {
                Id = table.Column<int>(type: "int", nullable: false)
                    .Annotation("SqlServer:Identity", "1, 1"),
                Title = table.Column<string>(type: "nvarchar(max)", nullable: true),
                ReleaseDate = table.Column<DateTime>(type: "datetime2", nullable: false),
                Genre = table.Column<string>(type: "nvarchar(max)", nullable: true),
                Price = table.Column<decimal>(type: "decimal(18,2)", nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Movie", x => x.Id);
            });
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropTable(
            name: "Movie");
    }
}

Dalam kode sebelumnya:

  • InitialCreate.Up membuat tabel Film dan mengonfigurasi Id sebagai kunci utama.
  • InitialCreate.Down mengembalikan perubahan skema yang Up dibuat oleh migrasi.

Injeksi dependensi di pengontrol

Controllers/MoviesController.cs Buka file dan periksa konstruktor:

public class MoviesController : Controller
{
    private readonly MvcMovieContext _context;

    public MoviesController(MvcMovieContext context)
    {
        _context = context;
    }

Konstruktor menggunakan Injeksi Dependensi untuk menyuntikkan konteks database (MvcMovieContext) ke pengontrol. Konteks database digunakan dalam setiap metode CRUD di pengontrol.

Uji halaman Buat . Masukkan dan kirim data.

Uji halaman Edit, Detail, dan Hapus .

Model yang sangat ditik dan direktif @model

Sebelumnya dalam tutorial ini, Anda melihat bagaimana pengontrol dapat meneruskan data atau objek ke tampilan menggunakan ViewData kamus. ViewData Kamus adalah objek dinamis yang menyediakan cara terikat terlambat yang nyaman untuk meneruskan informasi ke tampilan.

MVC menyediakan kemampuan untuk meneruskan objek model yang ditik dengan kuat ke tampilan. Pendekatan yang sangat ditik ini memungkinkan pemeriksaan kode waktu kompilasi. Mekanisme perancah melewati model yang ditik dengan kuat di MoviesController kelas dan tampilan.

Periksa metode yang dihasilkan Details dalam Controllers/MoviesController.cs file:

// GET: Movies/Details/5
public async Task<IActionResult> Details(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie
        .FirstOrDefaultAsync(m => m.Id == id);
    if (movie == null)
    {
        return NotFound();
    }

    return View(movie);
}

Parameter id umumnya diteruskan sebagai data rute. Misalnya, https://localhost:5001/movies/details/1 set:

  • Pengontrol ke movies pengontrol, segmen URL pertama.
  • Tindakan untuk details, segmen URL kedua.
  • Ke id 1, segmen URL terakhir.

id dapat diteruskan dengan string kueri, seperti dalam contoh berikut:

https://localhost:5001/movies/details?id=1

Parameter id didefinisikan sebagai jenis nullable (int?) dalam kasus ketika id nilai tidak disediakan.

Ekspresi lambda diteruskan ke FirstOrDefaultAsync metode untuk memilih entitas film yang cocok dengan data rute atau nilai string kueri.

var movie = await _context.Movie
    .FirstOrDefaultAsync(m => m.Id == id);

Jika film ditemukan, instans Movie model diteruskan ke Details tampilan:

return View(movie);

Periksa isi Views/Movies/Details.cshtml file:

@model MvcMovie.Models.Movie

@{
    ViewData["Title"] = "Details";
}

<h1>Details</h1>

<div>
    <h4>Movie</h4>
    <hr />
    <dl class="row">
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Title)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Title)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.ReleaseDate)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.ReleaseDate)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Genre)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Genre)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Price)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Price)
        </dd>
    </dl>
</div>
<div>
    <a asp-action="Edit" asp-route-id="@Model.Id">Edit</a> |
    <a asp-action="Index">Back to List</a>
</div>

Pernyataan @model di bagian atas file tampilan menentukan jenis objek yang diharapkan tampilan. Ketika pengontrol film dibuat, pernyataan berikut @model disertakan:

@model MvcMovie.Models.Movie

Arahan ini @model memungkinkan akses ke film yang diteruskan pengontrol ke tampilan. Objek Model dititik dengan kuat. Misalnya, dalam Details.cshtml tampilan, kode meneruskan setiap bidang film ke pembantu DisplayNameFor HTML dan DisplayFor dengan objek yang di ketik Model dengan kuat. Metode Create dan Edit dan tampilan juga meneruskan Movie objek model.

Index.cshtml Periksa tampilan dan Index metode di pengontrol Film. Perhatikan bagaimana kode membuat List objek saat memanggil View metode . Kode meneruskan daftar ini Movies dari Index metode tindakan ke tampilan:

// GET: Movies
public async Task<IActionResult> Index()
{
    return View(await _context.Movie.ToListAsync());
}

Ketika pengontrol film dibuat, perancah menyertakan pernyataan berikut @model di bagian Index.cshtml atas file:

@model IEnumerable<MvcMovie.Models.Movie>

Direktif @model memungkinkan akses ke daftar film yang diteruskan pengontrol ke tampilan dengan menggunakan Model objek yang sangat diketik. Misalnya, dalam Index.cshtml tampilan, kode mengulang melalui film dengan pernyataan di atas objek yang foreach sangat di ketik Model :

@model IEnumerable<MvcMovie.Models.Movie>

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Model Karena objek sangat ditik sebagai IEnumerable<Movie> objek, setiap item dalam perulangan di ketik sebagai Movie. Di antara manfaat lainnya, kompilator memvalidasi jenis yang digunakan dalam kode.

Pengelogan SQL Core Kerangka Kerja Entitas

Konfigurasi pengelogan biasanya disediakan oleh bagian Logging dari file appsettings.{Environment}.json. Untuk mencatat pernyataan SQL, tambahkan "Microsoft.EntityFrameworkCore.Database.Command": "Information" ke appsettings.Development.json file:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=MyDB-2;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
     ,"Microsoft.EntityFrameworkCore.Database.Command": "Information"
    }
  },
  "AllowedHosts": "*"
}

Dengan JSON sebelumnya, pernyataan SQL ditampilkan pada baris perintah dan di jendela output Visual Studio.

Untuk informasi selengkapnya, lihat Pengelogan di .NET Core dan ASP.NET Core dan masalah GitHub ini.

Sumber Daya Tambahan:

Dalam tutorial ini, kelas ditambahkan untuk mengelola film dalam database. Kelas-kelas ini adalah bagian "Model" dari aplikasi MVC.

Kelas model ini digunakan dengan Entity Framework Core (EF Core) untuk bekerja dengan database. EF Core adalah kerangka kerja pemetaan relasional objek (ORM) yang menyederhanakan kode akses data yang harus Anda tulis.

Kelas model yang dibuat dikenal sebagai kelas POCO, dari Plain Old CLR Objects. Kelas POCO tidak memiliki dependensi pada EF Core. Mereka hanya menentukan properti data yang akan disimpan dalam database.

Dalam tutorial ini, kelas model dibuat terlebih dahulu, dan EF Core membuat database.

Menambahkan kelas model data

Klik kanan folder >Model Tambahkan>Kelas. Beri nama file Movie.cs.

Movie.cs Perbarui file dengan kode berikut:

using System;
using System.ComponentModel.DataAnnotations;

namespace MvcMovie.Models
{
    public class Movie
    {
        public int Id { get; set; }
        public string Title { get; set; }

        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; }
        public decimal Price { get; set; }
    }
}

Kelas Movie berisi Id bidang, yang diperlukan oleh database untuk kunci utama.

Atribut DataType pada ReleaseDate menentukan jenis data (Date). Dengan atribut ini:

  • Pengguna tidak diharuskan memasukkan informasi waktu di bidang tanggal.
  • Hanya tanggal yang ditampilkan, bukan informasi waktu.

DataAnnotations dibahas dalam tutorial selanjutnya.

Menambahkan paket NuGet

Dari menu Alat, pilih NuGet Package Manager>Package Manager Console (PMC).

Menu PMC

Di PMC, jalankan perintah berikut:

Install-Package Microsoft.EntityFrameworkCore.SqlServer

Perintah sebelumnya menambahkan EF Core penyedia SQL Server. Paket penyedia menginstal EF Core paket sebagai dependensi. Paket tambahan diinstal secara otomatis di langkah perancah nanti dalam tutorial.

Membuat kelas konteks database

Kelas konteks database diperlukan untuk mengoordinasikan EF Core fungsionalitas (Buat, Baca, Perbarui, Hapus) untuk model.Movie Konteks database berasal dari Microsoft.EntityFrameworkCore.DbContext dan menentukan entitas yang akan disertakan dalam model data.

Membuat folder Data .

Data/MvcMovieContext.cs Tambahkan file dengan kode berikut:

using Microsoft.EntityFrameworkCore;
using MvcMovie.Models;

namespace MvcMovie.Data
{
    public class MvcMovieContext : DbContext
    {
        public MvcMovieContext (DbContextOptions<MvcMovieContext> options)
            : base(options)
        {
        }

        public DbSet<Movie> Movie { get; set; }
    }
}

Kode sebelumnya membuat properti DbSet<Movie> untuk kumpulan entitas. Dalam terminologi Entity Framework, kumpulan entitas biasanya sesuai dengan tabel database. Entitas sesuai dengan baris dalam tabel.

Mendaftarkan konteks database

ASP.NET Core dibangun dengan injeksi dependensi (DI). Layanan (seperti EF Core konteks DB) harus didaftarkan dengan DI selama pengaktifan aplikasi. Komponen yang memerlukan layanan ini (seperti Razor Pages) disediakan melalui parameter konstruktor. Kode konstruktor yang mendapatkan instans konteks DB ditampilkan nanti dalam tutorial. Di bagian ini, Anda mendaftarkan konteks database dengan kontainer DI.

Tambahkan pernyataan berikut using di bagian Startup.csatas :

using MvcMovie.Data;
using Microsoft.EntityFrameworkCore;

Tambahkan kode yang disorot berikut di Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();

    services.AddDbContext<MvcMovieContext>(options =>
    options.UseSqlServer(Configuration.GetConnectionString("MvcMovieContext")));
}

Nama string koneksi diteruskan ke konteks dengan memanggil metode pada DbContextOptions objek. Untuk pengembangan lokal, sistem konfigurasi ASP.NET Core membaca string koneksi dari appsettings.json file.

Memeriksa string koneksi database

Tambahkan string koneksi ke appsettings.json file:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "MvcMovieContext": "Server=(localdb)\\mssqllocaldb;Database=MvcMovieContext-1;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

Buat proyek sebagai pemeriksaan kesalahan pengkompilasi.

Halaman film Perancah

Gunakan alat perancah untuk menghasilkan halaman Buat, Baca, Perbarui, dan Hapus (CRUD) untuk model film.

Di Penjelajah Solusi, klik kanan folder > Pengontrol Tambahkan > Item Perancah Baru.

tampilan langkah di atas

Dalam dialog Tambahkan Perancah, pilih Pengontrol MVC dengan tampilan, menggunakan Tambahkan Kerangka Kerja > Entitas.

Tambahkan dialog Perancah

Selesaikan dialog Tambahkan Pengontrol :

  • Kelas model: Film (MvcMovie.Models)
  • Kelas konteks data: MvcMovieContext (MvcMovie.Data)

Menambahkan konteks Data

  • Tampilan: Pertahankan default setiap opsi dicentang
  • Nama pengontrol: Pertahankan MoviesController default
  • Pilih Tambahkan

Visual Studio membuat:

  • Pengontrol film (Controllers/MoviesController.cs)
  • Razor lihat file untuk halaman Buat, Hapus, Detail, Edit, dan Indeks (*Views/Movies/'.cshtml')

Pembuatan otomatis file-file ini dikenal sebagai perancah.

Anda belum dapat menggunakan halaman perancah karena database belum ada. Jika Anda menjalankan aplikasi dan mengklik tautan Aplikasi Film, Anda mendapatkan tidak dapat membuka database atau tidak ada tabel seperti itu: Pesan kesalahan film .

Migrasi awal

EF CoreGunakan fitur Migrasi untuk membuat database. Migrasi adalah sekumpulan alat yang memungkinkan Anda membuat dan memperbarui database agar sesuai dengan model data Anda.

Dari menu Alat, pilih NuGet Package Manager>Package Manager Console (PMC).

Di PMC, masukkan perintah berikut:

Add-Migration InitialCreate
Update-Database
  • Add-Migration InitialCreate: Menghasilkan Migrations/{timestamp}_InitialCreate.cs file migrasi. Argumen InitialCreate adalah nama migrasi. Nama apa pun dapat digunakan, tetapi menurut konvensi, nama dipilih yang menjelaskan migrasi. Karena ini adalah migrasi pertama, kelas yang dihasilkan berisi kode untuk membuat skema database. Skema database didasarkan pada model yang ditentukan di MvcMovieContext kelas .

  • Update-Database: Memperbarui database ke migrasi terbaru, yang dibuat perintah sebelumnya. Perintah ini menjalankan Up metode dalam Migrations/{time-stamp}_InitialCreate.cs file, yang membuat database.

    Perintah pembaruan database menghasilkan peringatan berikut:

    Tidak ada jenis yang ditentukan untuk kolom desimal 'Harga' pada jenis entitas 'Film'. Ini akan menyebabkan nilai terpotong secara diam-diam jika tidak cocok dalam presisi dan skala default. Tentukan jenis kolom server SQL secara eksplisit yang dapat mengakomodasi semua nilai menggunakan 'HasColumnType()'.

    Anda dapat mengabaikan peringatan itu, itu akan diperbaiki dalam tutorial selanjutnya.

Untuk informasi selengkapnya tentang alat PMC untuk EF Core, lihat EF Core referensi alat - PMC di Visual Studio.

Kelas InitialCreate

Periksa Migrations/{timestamp}_InitialCreate.cs file migrasi:

public partial class InitialCreate : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(
            name: "Movie",
            columns: table => new
            {
                Id = table.Column<int>(nullable: false)
                    .Annotation("SqlServer:ValueGenerationStrategy", 
                                 SqlServerValueGenerationStrategy.IdentityColumn),
                Title = table.Column<string>(nullable: true),
                ReleaseDate = table.Column<DateTime>(nullable: false),
                Genre = table.Column<string>(nullable: true),
                Price = table.Column<decimal>(nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Movie", x => x.Id);
            });
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropTable(
            name: "Movie");
    }
}

Metode Up ini membuat tabel Film dan mengonfigurasi Id sebagai kunci utama. Metode mengembalikan Down perubahan skema yang Up dibuat oleh migrasi.

Menguji aplikasi

  • Jalankan aplikasi dan klik tautan Aplikasi Film.

    Jika Anda mendapatkan pengecualian yang mirip dengan salah satu hal berikut ini:

SqlException: Cannot open database "MvcMovieContext-1" requested by the login. The login failed.

Anda mungkin melewatkan langkah migrasi.

  • Uji halaman Buat . Masukkan dan kirim data.

    Catatan

    Anda mungkin tidak dapat memasukkan koma desimal di Price bidang . Untuk mendukung validasi jQuery untuk lokal non-Bahasa Inggris yang menggunakan koma (",") untuk titik desimal dan untuk format tanggal non-Bahasa Inggris AS, aplikasi harus di globalisasi. Untuk instruksi globalisasi, lihat masalah GitHub ini.

  • Uji halaman Edit, Detail, dan Hapus .

Injeksi dependensi di pengontrol

Controllers/MoviesController.cs Buka file dan periksa konstruktor:

public class MoviesController : Controller
{
    private readonly MvcMovieContext _context;

    public MoviesController(MvcMovieContext context)
    {
        _context = context;
    }

Konstruktor menggunakan Injeksi Dependensi untuk menyuntikkan konteks database (MvcMovieContext) ke pengontrol. Konteks database digunakan dalam setiap metode CRUD di pengontrol.

Model yang di ketik dengan kuat dan @model kata kunci

Sebelumnya dalam tutorial ini, Anda melihat bagaimana pengontrol dapat meneruskan data atau objek ke tampilan menggunakan ViewData kamus. ViewData Kamus adalah objek dinamis yang menyediakan cara terikat terlambat yang nyaman untuk meneruskan informasi ke tampilan.

MVC juga menyediakan kemampuan untuk meneruskan objek model yang ditik dengan kuat ke tampilan. Pendekatan yang sangat ditik ini memungkinkan pemeriksaan kode waktu kompilasi. Mekanisme perancah menggunakan pendekatan ini (yaitu, melewati model yang sangat ditik) dengan MoviesController kelas dan tampilan.

Periksa metode yang dihasilkan Details dalam Controllers/MoviesController.cs file:

// GET: Movies/Details/5
public async Task<IActionResult> Details(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie
        .FirstOrDefaultAsync(m => m.Id == id);
    if (movie == null)
    {
        return NotFound();
    }

    return View(movie);
}

Parameter id umumnya diteruskan sebagai data rute. https://localhost:5001/movies/details/1 Misalnya set:

  • Pengontrol ke movies pengontrol (segmen URL pertama).
  • Tindakan ke details (segmen URL kedua).
  • Id ke 1 (segmen URL terakhir).

Anda juga bisa meneruskan id dengan string kueri sebagai berikut:

https://localhost:5001/movies/details?id=1

Parameter id didefinisikan sebagai jenis nullable (int?) jika nilai ID tidak disediakan.

Ekspresi lambda diteruskan ke untuk FirstOrDefaultAsync memilih entitas film yang cocok dengan data rute atau nilai string kueri.

var movie = await _context.Movie
    .FirstOrDefaultAsync(m => m.Id == id);

Jika film ditemukan, instans Movie model diteruskan ke Details tampilan:

return View(movie);

Periksa isi Views/Movies/Details.cshtml file:

@model MvcMovie.Models.Movie

@{
    ViewData["Title"] = "Details";
}

<h1>Details</h1>

<div>
    <h4>Movie</h4>
    <hr />
    <dl class="row">
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Title)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Title)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.ReleaseDate)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.ReleaseDate)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Genre)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Genre)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Price)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Price)
        </dd>
    </dl>
</div>
<div>
    <a asp-action="Edit" asp-route-id="@Model.Id">Edit</a> |
    <a asp-action="Index">Back to List</a>
</div>

Pernyataan @model di bagian atas file tampilan menentukan jenis objek yang diharapkan tampilan. Ketika pengontrol film dibuat, pernyataan berikut @model disertakan:

@model MvcMovie.Models.Movie

Arahan ini @model memungkinkan akses ke film yang diteruskan pengontrol ke tampilan. Objek Model dititik dengan kuat. Misalnya, dalam Details.cshtml tampilan, kode meneruskan setiap bidang film ke pembantu DisplayNameFor HTML dan DisplayFor dengan objek yang di ketik Model dengan kuat. Metode Create dan Edit dan tampilan juga meneruskan Movie objek model.

Index.cshtml Periksa tampilan dan Index metode di pengontrol Film. Perhatikan bagaimana kode membuat List objek saat memanggil View metode . Kode meneruskan daftar ini Movies dari Index metode tindakan ke tampilan:

// GET: Movies
public async Task<IActionResult> Index()
{
    return View(await _context.Movie.ToListAsync());
}

Ketika pengontrol film dibuat, perancah menyertakan pernyataan berikut @model di bagian Index.cshtml atas file:

@model IEnumerable<MvcMovie.Models.Movie>

Direktif @model ini memungkinkan Anda mengakses daftar film yang diteruskan pengontrol ke tampilan dengan menggunakan Model objek yang sangat diketik. Misalnya, dalam Index.cshtml tampilan, kode mengulang melalui film dengan pernyataan di atas objek yang foreach sangat di ketik Model :

@model IEnumerable<MvcMovie.Models.Movie>

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Karena objek sangat di Model ketik (sebagai IEnumerable<Movie> objek), setiap item dalam perulangan di ketik sebagai Movie. Di antara manfaat lainnya, ini berarti Anda mendapatkan pemeriksaan waktu kompilasi kode.

Sumber Daya Tambahan: