Sdílet prostřednictvím


Přidání nového pole

Rick Anderson

Poznámka:

Aktualizovaná verze tohoto kurzu je k dispozici zde pomocí nejnovější verze sady Visual Studio. Nový kurz používá ASP.NET Core MVC, který poskytuje mnoho vylepšení v tomto kurzu.

V tomto kurzu se naučíte ASP.NET Core MVC s řadiči a zobrazeními. Razor Pages je nová alternativa v ASP.NET Core, což je programovací model založený na stránkách, který usnadňuje a zvyšuje produktivitu vytváření webového uživatelského rozhraní. Doporučujeme vyzkoušet kurz Razor Pages před verzí MVC. Kurz Razor Pages:

  • Je jednodušší postupovat.
  • Obsahuje další funkce.
  • Je upřednostňovaným přístupem pro vývoj nových aplikací.

V této části použijete Migrace Entity Framework Code First k migraci některých změn do tříd modelu, aby se změna použila na databázi.

Když ve výchozím nastavení použijete Entity Framework Code First k automatickému vytvoření databáze, jak jste to udělali dříve v tomto kurzu, Code First přidá do databáze tabulku, která pomáhá sledovat, jestli je schéma databáze synchronizované se třídami modelu, ze které byla vygenerována. Pokud nejsou synchronizované, Entity Framework vyvolá chybu. To usnadňuje sledování problémů v době vývoje, které byste jinak mohli v době běhu jenom najít (nejasnými chybami).

Nastavení Migrace Code First pro změny modelu

Přejděte na Průzkumník řešení. Klikněte pravým tlačítkem na soubor Movies.mdf a výběrem možnosti Odstranit odeberte databázi filmů. Pokud nevidíte soubor Movies.mdf , klikněte na ikonu Zobrazit všechny soubory zobrazenou níže v červené osnově.

Snímek obrazovky znázorňující kartu Řadiče filmů s tečkou c a Průzkumník řešení otevřít Ikona Zobrazit všechny soubory je zakroužkovaná červeně.

Sestavte aplikaci, abyste měli jistotu, že nedošlo k žádným chybám.

V nabídce Nástroje klikněte na Správce balíčků NuGet a pak na Konzola Správce balíčků.

Přidat člověka balíčku

V okně konzoly Správce balíčků na příkazovém PM> řádku zadejte

Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDBContext

Snímek obrazovky znázorňující okno konzoly Správce balíčků Text v příkazu Povolit migraci je zvýrazněný.

Příkaz Enable-Migrations (viz výše) vytvoří soubor Configuration.cs v nové složce Migrations .

Snímek obrazovky znázorňující Průzkumník řešení Je vybrána podsložka konfigurace c složky Migrations.

Visual Studio otevře soubor Configuration.cs . Nahraďte metodu Seed v souboru Configuration.cs následujícím kódem:

protected override void Seed(MvcMovie.Models.MovieDBContext context)
{
    context.Movies.AddOrUpdate( i => i.Title,
        new Movie
        {
            Title = "When Harry Met Sally",
            ReleaseDate = DateTime.Parse("1989-1-11"),
            Genre = "Romantic Comedy",
            Price = 7.99M
        },

         new Movie
         {
             Title = "Ghostbusters ",
             ReleaseDate = DateTime.Parse("1984-3-13"),
             Genre = "Comedy",
             Price = 8.99M
         },

         new Movie
         {
             Title = "Ghostbusters 2",
             ReleaseDate = DateTime.Parse("1986-2-23"),
             Genre = "Comedy",
             Price = 9.99M
         },

       new Movie
       {
           Title = "Rio Bravo",
           ReleaseDate = DateTime.Parse("1959-4-15"),
           Genre = "Western",
           Price = 3.99M
       }
   );
   
}

Najeďte myší na červenou vlnovku pod Movie a klikněte na Show Potential Fixes příkaz MvcMovie.Models;

Snímek obrazovky s nabídkou Zobrazit potenciální opravy Je vybrána možnost M V C Movie dot Models a zobrazí se upozornění, které nelze najít.

Tím přidáte následující příkaz using:

using MvcMovie.Models;

Poznámka:

Migrace Code First volá metodu Seed po každé migraci (tj. volání aktualizační databáze v konzole Správce balíčků) a tato metoda aktualizuje řádky, které už byly vloženy, nebo je vloží, pokud ještě neexistují.

Metoda AddOrUpdate v následujícím kódu provádí operaci upsert:

context.Movies.AddOrUpdate(i => i.Title,
    new Movie
    {
        Title = "When Harry Met Sally",
        ReleaseDate = DateTime.Parse("1989-1-11"),
        Genre = "Romantic Comedy",
        Rating = "PG",
        Price = 7.99M
    }

Vzhledem k tomu, že metoda Seed běží s každou migrací, nemůžete jenom vložit data, protože řádky, které se pokoušíte přidat, již budou existovat po první migraci, která vytvoří databázi. Operace upsert zabraňuje chybám, ke kterým by došlo, pokud se pokusíte vložit řádek, který již existuje, ale přepíše všechny změny dat, které jste mohli provést při testování aplikace. U testovacích dat v některých tabulkách možná nebudete chtít, aby k tomu došlo: v některých případech při změně dat při testování chcete, aby změny zůstaly po aktualizacích databáze. V takovém případě chcete provést operaci podmíněného vložení: vložte řádek jenom v případě, že ještě neexistuje.

První parametr předaný metodě AddOrUpdate určuje vlastnost, která se má použít ke kontrole, zda řádek již existuje. Pro data testovacího videa, která poskytujete, lze vlastnost použít pro tento účel, Title protože každý název v seznamu je jedinečný:

context.Movies.AddOrUpdate(i => i.Title,

Tento kód předpokládá, že názvy jsou jedinečné. Pokud ručně přidáte duplicitní název, při příští migraci se zobrazí následující výjimka.

Sekvence obsahuje více než jeden prvek.

Další informace o metodě AddOrUpdate naleznete v tématu Péče o EF 4.3 AddOrUpdate Method..

Stisknutím kombinace kláves CTRL-SHIFT-B sestavte projekt.(Pokud se v tomto okamžiku nevytvořijí, následující kroky selžou.)

Dalším krokem je vytvoření DbMigration třídy pro počáteční migraci. Tato migrace vytvoří novou databázi, proto jste odstranili soubor movie.mdf v předchozím kroku.

V okně konzoly Správce balíčků zadejte příkaz add-migration Initial pro vytvoření počáteční migrace. Název "Počáteční" je libovolný a slouží k pojmenování vytvořeného souboru migrace.

Snímek obrazovky znázorňující konzolu Správce balíčků Text v příkazu pro přidání migrace je zvýrazněný.

Migrace Code First vytvoří jiný soubor třídy v Složka Migrace (s názvem {DateStamp}_Initial.cs) a tato třída obsahuje kód, který vytvoří schéma databáze. Název souboru migrace je předem opravený časovým razítkem, které vám pomůže se řazením. Prozkoumejte soubor {DateStamp}_Initial.cs, který obsahuje pokyny k vytvoření Movies tabulky pro Movie DB. Při aktualizaci databáze v následujících pokynech se tento soubor {DateStamp}_Initial.cs spustí a vytvoří schéma databáze. Potom se spustí metoda Seed , která naplní databázi testovacími daty.

V konzole Správce balíčků zadejte příkazupdate-database, který vytvoří databázi a spustí metoduSeed.

Snímek obrazovky znázorňující konzolu Správce balíčků Příkaz aktualizovat databázi je v okně.

Pokud se zobrazí chyba, která značí, že tabulka již existuje a nelze ji vytvořit, pravděpodobně proto, že jste aplikaci spustili po odstranění databáze a před spuštěním update-database. V takovém případě odstraňte soubor Movies.mdf znovu a zkuste update-database příkaz zopakovat. Pokud se vám stále zobrazuje chyba, odstraňte složku a obsah migrace a začněte pokyny v horní části této stránky (tím odstraníte soubor Movies.mdf a pak pokračujte k povolení migrace). Pokud se zobrazí chyba, otevřete SQL Server Průzkumník objektů a odeberte databázi ze seznamu. Pokud se zobrazí chyba oznamující, že soubor nelze připojit .mdf jako databázi, odeberte vlastnost Initial Catalog jako součást připojovací řetězec v souboru web.config.

Spusťte aplikaci a přejděte na adresu URL /Movies . Zobrazí se počáteční data.

Snímek obrazovky znázorňující index filmu M V C se čtyřmi uvedenými filmy

Přidání vlastnosti hodnocení do filmového modelu

Začněte přidáním nové Rating vlastnosti do existující Movie třídy. Otevřete soubor Models\Movie.cs a přidejte Rating tuto vlastnost:

public string Rating { get; set; }

Úplná Movie třída teď vypadá jako následující kód:

public class Movie
{
    public int ID { get; set; }
    public string Title { get; set; }

    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    public DateTime ReleaseDate { get; set; }
    public string Genre { get; set; }
    public decimal Price { get; set; }
    public string Rating { get; set; }
}

Sestavte aplikaci (Ctrl+Shift+B).

Protože jste do Movie třídy přidali nové pole, musíte také aktualizovat seznam povolených vazeb, aby tato nová vlastnost byla zahrnuta. bind Aktualizujte atribut pro Create metody Edit akcí tak, aby zahrnovaly Rating vlastnost:

[Bind(Include = "ID,Title,ReleaseDate,Genre,Price,Rating")]

Abyste mohli zobrazit, vytvořit a upravit novou Rating vlastnost v zobrazení prohlížeče, musíte také aktualizovat šablony zobrazení.

Otevřete soubor \Views\Movies\Index.cshtml a přidejte <th>Rating</th> záhlaví sloupce hned za sloupec Cena. Potom přidejte <td> sloupec na konec šablony, který hodnotu vykreslí @item.Rating . Níže je vidět, jak aktualizovaná šablona zobrazení Index.cshtml vypadá:

@model IEnumerable<MvcMovie.Models.Movie>
@{
    ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
    @Html.ActionLink("Create New", "Create")
    @using (Html.BeginForm("Index", "Movies", FormMethod.Get))
    {
    <p>
        Genre: @Html.DropDownList("movieGenre", "All")
        Title: @Html.TextBox("SearchString")
        <input type="submit" value="Filter" />
    </p>
    }
</p>
<table class="table">
    <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>
            @Html.DisplayNameFor(model => model.Rating)
        </th>

        <th></th>
    </tr>

@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>
            @Html.DisplayFor(modelItem => item.Rating)
        </td>

        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
            @Html.ActionLink("Details", "Details", new { id=item.ID }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.ID })
        </td>
    </tr>
}

</table>

Dále otevřete soubor \Views\Movies\Create.cshtml a přidejte Rating pole s následujícím zvýrazněným kódem. Tím se vykreslí textové pole, abyste mohli určit hodnocení při vytvoření nového filmu.

<div class="form-group">
            @Html.LabelFor(model => model.Price, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Rating, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Rating, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Rating, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Aktualizovali jste kód aplikace tak, aby podporoval novou Rating vlastnost.

Spusťte aplikaci a přejděte na adresu URL /Movies . Když to ale uděláte, zobrazí se jedna z následujících chyb:

Snímek obrazovky znázorňující neošetřenou chybu uživatele výjimky

Model, který zálohuje kontext MovieDBContext, se od vytvoření databáze změnil. Zvažte použití Migrace Code First k aktualizaci databáze (https://go.microsoft.com/fwlink/?LinkId=238269).

Snímek obrazovky s prohlížečem s chybou serveru oznámení v aplikaci

Tato chyba se zobrazuje, protože aktualizovaná Movie třída modelu v aplikaci se teď liší od schématu Movie tabulky existující databáze. (V tabulce databáze není žádný Rating sloupec.)

K vyřešení chyby existuje několik přístupů:

  1. Rozhraní Entity Framework automaticky vyřaďte a znovu vytvořte databázi na základě nového schématu třídy modelu. Tento přístup je velmi pohodlný v rané fázi vývojového cyklu, když provádíte aktivní vývoj v testovací databázi; umožňuje rychle vyvíjet schéma modelu a databáze společně. Nevýhodou ale je, že ztratíte stávající data v databázi , takže tento přístup nechcete používat v produkční databázi! Použití inicializátoru k automatickému sesílování databáze s testovacími daty je často produktivní způsob vývoje aplikace. Další informace o inicializátorech databází Entity Framework najdete v kurzu ASP.NET MVC/Entity Framework.
  2. Explicitně upravte schéma existující databáze tak, aby odpovídalo třídám modelu. Výhodou tohoto přístupu je, že data uchováváte. Tuto změnu můžete provést ručně nebo vytvořením skriptu pro změnu databáze.
  3. K aktualizaci schématu databáze použijte Migrace Code First.

Pro účely tohoto kurzu použijeme Migrace Code First.

Aktualizujte metodu Seed tak, aby poskytovala hodnotu pro nový sloupec. Otevřete Migrations\Configuration.cs soubor a přidejte pole Hodnocení do každého objektu Movie.

new Movie
{
    Title = "When Harry Met Sally",
    ReleaseDate = DateTime.Parse("1989-1-11"),
    Genre = "Romantic Comedy",
    Rating = "PG",
    Price = 7.99M
},

Sestavte řešení a otevřete okno konzoly Správce balíčků a zadejte následující příkaz:

add-migration Rating

Příkaz add-migration informuje architekturu migrace, aby prozkoumal aktuální model videa se schématem aktuální databáze filmů a vytvořil potřebný kód pro migraci databáze do nového modelu. Název Hodnocení je libovolný a slouží k pojmenování souboru migrace. Je užitečné použít smysluplný název kroku migrace.

Po dokončení tohoto příkazu visual Studio otevře soubor třídy, který definuje novou DbMigration odvozenou třídu, a v Up metodě uvidíte kód, který vytvoří nový sloupec.

public partial class AddRatingMig : DbMigration
{
    public override void Up()
    {
        AddColumn("dbo.Movies", "Rating", c => c.String());
    }
    
    public override void Down()
    {
        DropColumn("dbo.Movies", "Rating");
    }
}

Sestavte řešení a pak zadejte update-database příkaz v okně konzoly Správce balíčků.

Následující obrázek znázorňuje výstup v okně konzoly Správce balíčků (Hodnocení předběžného razítka data se bude lišit.)

Snímek obrazovky znázorňující okno konzoly Správce balíčků se zadaným příkazem pro aktualizaci databáze

Znovu spusťte aplikaci a přejděte na adresu URL /Movies. Zobrazí se nové pole Hodnocení.

Snímek obrazovky znázorňující seznam indexu filmů V s přidaným polem Hodnocení

Kliknutím na odkaz Vytvořit nový přidáte nový film. Všimněte si, že můžete přidat hodnocení.

7_CreateRioII

Klikněte na Vytvořit. Nový film, včetně hodnocení, se teď zobrazí ve výpisu filmů:

7_ourNewMovie_SM

Teď, když projekt používá migrace, nebudete muset databázi odstranit, když přidáte nové pole nebo jinak aktualizujete schéma. V další části provedeme další změny schématu a použijeme migrace k aktualizaci databáze.

Pole byste také měli přidat Rating do šablon zobrazení Upravit, Podrobnosti a Odstranit.

V okně konzoly Správce balíčků znovu můžete zadat příkaz update-database a nespustí se žádný kód migrace, protože schéma odpovídá modelu. Spuštěním příkazu update-database se však metoda znovu spustí Seed a pokud jste změnili některá z počátečních dat, změny budou ztraceny, protože Seed metoda upsertuje data. Další informace o Seed metodě najdete v oblíbené ASP.NET m kurzu k MVC/Entity Frameworku tomA Dykstra.

V této části jste viděli, jak můžete upravovat objekty modelu a udržovat databázi synchronizovanou se změnami. Také jste se naučili, jak naplnit nově vytvořenou databázi ukázkovými daty, abyste si mohli vyzkoušet scénáře. Toto byl jen rychlý úvod do code First, viz Vytvoření datového modelu Entity Framework pro aplikaci ASP.NET MVC , kde najdete podrobnější kurz k tomuto tématu. Dále se podíváme na to, jak můžete do tříd modelu přidat bohatší logiku ověřování a povolit vynucení některých obchodních pravidel.