ASP.NET Core 3.0 Razor Pages 事始め(3) - マイグレーションのやり直しとURLルーティング


## 記事目次

1. [ASP.NET Core 3.0 Razor Pages 事始め(1) - はじめてのRazor Pagesアプリケーション](https://qiita.com/gushwell/items/6d8b801923b639d9ea2e)
2. [ASP.NET Core 3.0 Razor Pages 事始め(2) - スキャフォールディングとDBマイグレーション](https://qiita.com/gushwell/items/7eb76edf7006c0f02be4)
3. [ASP.NET Core 3.0 Razor Pages 事始め(3) - マイグレーションのやり直しとURLルーティング](https://qiita.com/gushwell/items/7ebe70f0d6adfd10ae12) <-- この記事
4. [ASP.NET Core 3.0 Razor Pages 事始め(4) - ページモデルとページハンドラ](https://qiita.com/gushwell/items/1deac26aaed945cc8631)
5. [ASP.NET Core 3.0 Razor Pages 事始め(5) - Postページハンドラとタグヘルパー](https://qiita.com/gushwell/items/daf901d4d76301dadea7)
6. [ASP.NET Core 3.0 Razor Pages 事始め(6) - データベースに初期値を設定する](https://qiita.com/gushwell/items/f7be44e668a6e168fc61)
7. [ASP.NET Core 3.0 Razor Pages 事始め(7) - Viewの変更とコンカレンシー例外処理](https://qiita.com/gushwell/items/913e8e95a0a79949af3c)
8. [ASP.NET Core 3.0 Razor Pages 事始め(8) - 検索機能の追加](https://qiita.com/gushwell/items/134930aba1d181100547)
9. [ASP.NET Core 3.0 Razor Pages 事始め(9) - ページに新しいフィールドを追加する](https://qiita.com/gushwell/items/a330e592f76efda13c42)
10. [ASP.NET Core 3.0 Razor Pages 事始め(10) - 検証機能の追加](https://qiita.com/gushwell/items/12e180ef129ea6a05757)


---
<br>

前回[ASP.NET Core 3.0 Razor Pages 事始め(2)](https://qiita.com/gushwell/items/7eb76edf7006c0f02be4)の続きです。

今回はちょっと寄り道です。

## DBContextの プロパティ名を変更する

RazorPagesMovieContextクラスのソース見直していたら、

```c#
public DbSet<RazorPagesMovie.Models.Movie> Movie { get; set; }
``` 

とプロパティ名が単数形になってます。僕のタイプミスかなと思ったのですが、チュートリアルのコードが単数形になっていました。

やはり、複数形にしたいです。
ということで、Moviesと複数形に直したいと思います。

```c#
public DbSet<RazorPagesMovie.Models.Movie> Movies { get; set; }
``` 

これを参照している個所(cshtml ファイルも含めて）Movies に変更します。

Index.cshtml.cs 内の、Movie プロパティも Movies に変更します。


```c#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Data;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies
{
    public class IndexModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IList<Movie> Movies { get;set; }

        public async Task OnGetAsync()
        {
            Movies = await _context.Movies.ToListAsync();
        }
    }
}
```

併せて、Index.cshtml 内も変更します。


これで、ビルドし直し、F5キーで実行し、次のURLにアクセスします。

```
https://localhost:5001/Movies
```

あれ、 以下のようなエラーページが出てしまいました。

```
An unhandled exception occurred while processing the request.

SqliteException: SQLite Error 1: 'no such table: Movies'.
Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(int rc, sqlite3 db)
```

ああ、データベースのテーブル名と一致しないのでダメなんですね。

## SQLiteでのDBマイグレーション？

ということで、もう一回マイグレーションを実施します。


```sh
dotnet ef migrations add renameMoviesTable
dotnet ef database update
```

とやれば、できると思ったのですが、SQLiteでは制限があるようで失敗します。

なので、MvcMovie.db ファイルを削除後、Migrationsフォルダ以下を全て削除します。

それから以下のコマンドを再度実行します。

```sh
dotnet ef migrations add InitialCreate
dotnet ef database update
```

MvcMovie.db ファイルが再度作成されたことを確認後、F5キーで実行します。


直接、以下のURLにアクセスします。
```
https://localhost:5001/Movies
```

![スクリーンショット 2019-10-27 10.10.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29415/ffeebb87-810d-088c-1644-bc5d62c4bfb3.png "スクリーンショット 2019-10-27 10.10.18.png")


無事、/Movies/Index ページが起動できました。

SQLiteで本格的にアプリ開発するとき(そんなケースはあまりないと思いますが)はちょっと工夫が必要そうです。


## URLルーティング

ちょっと、ここで、RazorPagesのURLルーティングがどうなっているかを少し見てみます。

アプリを起動し、Privacy のリンクをクリックします。するとPrivacyページが開きます。この時の URLは、

```
https://localhost:5001/Privacy
```

です。

![スクリーンショット 2019-10-27 15.16.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29415/fcc17bab-2a7d-7059-c1f6-92a092b692a0.png "スクリーンショット 2019-10-27 15.16.25.png")



ページ名が、URLと対応しているのが分かります。

ちなみに、Startページ（index.cshtml)のURLは、

```
https://localhost:5001/
```

です。
プロジェクトのソースコードのどこを見ても、indexがデフォルトのページだという指定はありませんでした。
これはフレームワーク側で決めているようです。

当然ですが、ブラウザで、

```
https://localhost:5001/index
```

とURLを直接指定した場合も、indexページが表示されました。


さきほどの、MoviesのIndexページのURLも

```
https://localhost:5001/Movies
```

で、Movies/Index.cshtml が開きます。Createページの URLは、

```
https://localhost:5001/Movies/Create
```

です。実にわかりやすいです。

Pagesフォルダーに新たなフォルダを作成し、

/Pages/Sample/Hello.cshtml

というページを作成すれば、URLは、

```
https://localhost:5001/Sample/Hello 
```

となります。フォルダ階層がURLのパスと一致するので、とても分かりやすいです。

表にまとめてみました。

ファイル名とパス	| 一致するURL
--------------------------|---------------------
/Pages/Index.cshtml	| / または /Index
/Pages/Privacy.cshtml |	/Privacy
/Pages/Movies/Create.cshtml |	/Movies/Create
/Pages/Movies/Index.cshtml |	/Movies または /Movies/Index


---

今回は少し寄り道をしてしまいましたが、次回は、公式チュートリアルの[ASP.NET Core でスキャフォールディングされた Razor ページ](https://docs.microsoft.com/ja-jp/aspnet/core/tutorials/razor-pages/page?view=aspnetcore-3.0&tabs=visual-studio)をやっていこうと思います。