チュートリアル: 高度なシナリオについて学習する - ASP.NET MVC と EF CoreTutorial: Learn about advanced scenarios - ASP.NET MVC with EF Core

前のチュートリアルでは、Table-Per-Hierarchy 継承を実装しました。In the previous tutorial, you implemented table-per-hierarchy inheritance. このチュートリアルでは、Entity Framework Core を使用するより高度な ASP.NET Core Web アプリケーションを開発する際に、注意すべきいくつかのトピックを紹介します。This tutorial introduces several topics that are useful to be aware of when you go beyond the basics of developing ASP.NET Core web applications that use Entity Framework Core.

このチュートリアルでは、次の作業を行いました。In this tutorial, you:

  • 生 SQL クエリを実行するPerform raw SQL queries
  • エンティティを返すクエリを呼び出すCall a query to return entities
  • その他の型を返すクエリを呼び出すCall a query to return other types
  • 更新クエリを呼び出すCall an update query
  • SQL クエリを調べるExamine SQL queries
  • 抽象化レイヤーを作成するCreate an abstraction layer
  • 変更の自動検出について学習するLearn about Automatic change detection
  • EF Core のソース コードと開発計画について学習するLearn about EF Core source code and development plans
  • 動的な LINQ を使ってコードを簡略化する方法を学習するLearn how to use dynamic LINQ to simplify code

必須コンポーネントPrerequisites

生 SQL クエリを実行するPerform raw SQL queries

Entity Framework を使用する利点の 1 つは、データを格納する特定のメソッドにコードを過度に接近させなくてもよい点です。One of the advantages of using the Entity Framework is that it avoids tying your code too closely to a particular method of storing data. SQL クエリとコマンドが生成されるため、自分でこれらを記述する必要がなくなります。It does this by generating SQL queries and commands for you, which also frees you from having to write them yourself. ただし、例外的なシナリオがあります。手動で作成した特定の SQL クエリを実行する必要がある場合です。But there are exceptional scenarios when you need to run specific SQL queries that you have manually created. このようなシナリオでは、Entity Framework Code First API には、SQL コマンドをデータベースに直接渡せるメソッドが含まれています。For these scenarios, the Entity Framework Code First API includes methods that enable you to pass SQL commands directly to the database. EF Core 1.0 には次のオプションがあります。You have the following options in EF Core 1.0:

  • エンティティ型を返すクエリに対して DbSet.FromSql メソッドを使用します。Use the DbSet.FromSql method for queries that return entity types. 返されたオブジェクトは、DbSet オブジェクトで想定されている型である必要があります。また、追跡をオフにしている場合を除き、データベース コンテキストによって自動的に追跡されます。The returned objects must be of the type expected by the DbSet object, and they're automatically tracked by the database context unless you turn tracking off.

  • 非クエリ コマンドに対して Database.ExecuteSqlCommand を使用します。Use the Database.ExecuteSqlCommand for non-query commands.

エンティティではない型を返すクエリを実行する必要がある場合は、ADO.NET と EF で提供されるデータベース接続を使用できます。If you need to run a query that returns types that aren't entities, you can use ADO.NET with the database connection provided by EF. このメソッドを使用してエンティティ型を取得する場合でも、返されるデータはデータベース コンテキストによって追跡されません。The returned data isn't tracked by the database context, even if you use this method to retrieve entity types.

Web アプリケーションで SQL コマンドを実行する場合は常に、SQL インジェクション攻撃から自身のサイトを保護する対策を講じる必要があります。As is always true when you execute SQL commands in a web application, you must take precautions to protect your site against SQL injection attacks. これを行う 1 つの方法として、パラメーター化されたクエリを使用して、Web ページによって送信された文字列が SQL コマンドとして解釈できないことを確認します。One way to do that is to use parameterized queries to make sure that strings submitted by a web page can't be interpreted as SQL commands. このチュートリアルでは、ユーザー入力をクエリに統合するときに、パラメーター化されたクエリを使用します。In this tutorial you'll use parameterized queries when integrating user input into a query.

エンティティを返すクエリを呼び出すCall a query to return entities

DbSet<TEntity> クラスは、TEntity 型のエンティティを返すクエリの実行に使用できるメソッドを提供します。The DbSet<TEntity> class provides a method that you can use to execute a query that returns an entity of type TEntity. このしくみを確認するため、Department (部門) コントローラーの Details メソッド内のコードを変更します。To see how this works you'll change the code in the Details method of the Department controller.

DepartmentsController.csDetails メソッドで、次の強調表示されたコードに示されているように、部門を取得するコードを FromSql メソッドの呼び出しに置き換えます。In DepartmentsController.cs, in the Details method, replace the code that retrieves a department with a FromSql method call, as shown in the following highlighted code:

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

    string query = "SELECT * FROM Department WHERE DepartmentID = {0}";
    var department = await _context.Departments
        .FromSql(query, id)
        .Include(d => d.Administrator)
        .AsNoTracking()
        .SingleOrDefaultAsync();

    if (department == null)
    {
        return NotFound();
    }

    return View(department);
}

新しいコードが正しく動作することを確認するには、[Departments](部門) タブを選択し、いずれかの部門の [Details](詳細) を選択します。To verify that the new code works correctly, select the Departments tab and then Details for one of the departments.

部門の詳細

その他の型を返すクエリを呼び出すCall a query to return other types

以前に、登録日ごとの学生数を示す About ページ用に、学生の統計グリッドを作成しました。Earlier you created a student statistics grid for the About page that showed the number of students for each enrollment date. Students エンティティ セット (_context.Students) からデータを取得し、LINQ を使用して結果を EnrollmentDateGroup ビュー モデル オブジェクトに投影しました。You got the data from the Students entity set (_context.Students) and used LINQ to project the results into a list of EnrollmentDateGroup view model objects. LINQ を使用するのではなく、SQL そのものを記述するとします。Suppose you want to write the SQL itself rather than using LINQ. これを行うには、エンティティ オブジェクト以外のものを返す SQL クエリを実行する必要があります。To do that you need to run a SQL query that returns something other than entity objects. EF Core 1.0 では、これを行う方法の 1 つとして、ADO.NET コードを記述し、EF からデータベース接続を取得します。In EF Core 1.0, one way to do that is write ADO.NET code and get the database connection from EF.

HomeController.cs で、About メソッドを次のコードで置き換えます。In HomeController.cs, replace the About method with the following code:

public async Task<ActionResult> About()
{
    List<EnrollmentDateGroup> groups = new List<EnrollmentDateGroup>();
    var conn = _context.Database.GetDbConnection();
    try
    {
        await conn.OpenAsync();
        using (var command = conn.CreateCommand())
        {
            string query = "SELECT EnrollmentDate, COUNT(*) AS StudentCount "
                + "FROM Person "
                + "WHERE Discriminator = 'Student' "
                + "GROUP BY EnrollmentDate";
            command.CommandText = query;
            DbDataReader reader = await command.ExecuteReaderAsync();

            if (reader.HasRows)
            {
                while (await reader.ReadAsync())
                {
                    var row = new EnrollmentDateGroup { EnrollmentDate = reader.GetDateTime(0), StudentCount = reader.GetInt32(1) };
                    groups.Add(row);
                }
            }
            reader.Dispose();
        }
    }
    finally
    {
        conn.Close();
    }
    return View(groups);
}

using ステートメントを追加します。Add a using statement:

using System.Data.Common;

アプリを実行して [About] ページに移動します。Run the app and go to the About page. 以前に行ったのと同じデータが表示されます。It displays the same data it did before.

About ページ

更新クエリを呼び出すCall an update query

Contoso University の管理者が、すべてのコースの単位数を変更するなどの、データベースでグローバルな変更を実行するとします。Suppose Contoso University administrators want to perform global changes in the database, such as changing the number of credits for every course. 大学に多くのコースがある場合は、それらすべてをエンティティとして取得し、それらを個別に変更するのは非効率的です。If the university has a large number of courses, it would be inefficient to retrieve them all as entities and change them individually. このセクションでは、すべてのコースの単位数を変更する係数をユーザーが指定できるようにする Web ページを実装し、SQL UPDATE ステートメントを実行することによって変更を行います。In this section you'll implement a web page that enables the user to specify a factor by which to change the number of credits for all courses, and you'll make the change by executing a SQL UPDATE statement. Web ページは次の図のようになります。The web page will look like the following illustration:

Course Credits ページを更新する

CoursesContoller.cs で、HttpGet および HttpPost に UpdateCourseCredits メソッドを追加します。In CoursesContoller.cs, add UpdateCourseCredits methods for HttpGet and HttpPost:

public IActionResult UpdateCourseCredits()
{
    return View();
}
[HttpPost]
public async Task<IActionResult> UpdateCourseCredits(int? multiplier)
{
    if (multiplier != null)
    {
        ViewData["RowsAffected"] = 
            await _context.Database.ExecuteSqlCommandAsync(
                "UPDATE Course SET Credits = Credits * {0}",
                parameters: multiplier);
    }
    return View();
}

コントローラーが HttpGet 要求を処理するときに、ViewData["RowsAffected"] では何も返されず、前の図に示されているように、ビューに空のテキスト ボックスと、[送信] ボタンが表示されます。When the controller processes an HttpGet request, nothing is returned in ViewData["RowsAffected"], and the view displays an empty text box and a submit button, as shown in the preceding illustration.

[更新] ボタンをクリックすると、HttpPost メソッドが呼び出され、乗数がテキスト ボックスに入力した値になります。When the Update button is clicked, the HttpPost method is called, and multiplier has the value entered in the text box. このコードは次に、コースを更新し、影響を受けた行の数をViewData のビューに返す SQL を実行します。The code then executes the SQL that updates courses and returns the number of affected rows to the view in ViewData. ビューが RowsAffected 値を取得すると、更新された行の数を表示します。When the view gets a RowsAffected value, it displays the number of rows updated.

ソリューション エクスプローラーで、Views/Courses フォルダーを右クリックし、[追加] > [新しい項目] の順にクリックします。In Solution Explorer, right-click the Views/Courses folder, and then click Add > New Item.

[新しい項目の追加] ダイアログで、左側のウィンドウの [インストール済み] の下の [ASP.NET Core] をクリックし、[Razor ビュー] をクリックして、新しいビューに UpdateCourseCredits.cshtml という名前を付けます。In the Add New Item dialog, click ASP.NET Core under Installed in the left pane, click Razor View, and name the new view UpdateCourseCredits.cshtml.

Views/Courses/UpdateCourseCredits.cshtml で、テンプレート コードを次のコードに置き換えます。In Views/Courses/UpdateCourseCredits.cshtml, replace the template code with the following code:

@{
    ViewBag.Title = "UpdateCourseCredits";
}

<h2>Update Course Credits</h2>

@if (ViewData["RowsAffected"] == null)
{
    <form asp-action="UpdateCourseCredits">
        <div class="form-actions no-color">
            <p>
                Enter a number to multiply every course's credits by: @Html.TextBox("multiplier")
            </p>
            <p>
                <input type="submit" value="Update" class="btn btn-default" />
            </p>
        </div>
    </form>
}
@if (ViewData["RowsAffected"] != null)
{
    <p>
        Number of rows updated: @ViewData["RowsAffected"]
    </p>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

[Courses](コース) タブを選択してから、ブラウザーのアドレス バーで URL の末尾に "/UpdateCourseCredits" を追加して (例: http://localhost:5813/Courses/UpdateCourseCredits)、UpdateCourseCredits メソッドを実行します。Run the UpdateCourseCredits method by selecting the Courses tab, then adding "/UpdateCourseCredits" to the end of the URL in the browser's address bar (for example: http://localhost:5813/Courses/UpdateCourseCredits). テキスト ボックスに数値を入力します。Enter a number in the text box:

Course Credits ページを更新する

[更新] をクリックします。Click Update. 影響を受けた行の数が表示されます。You see the number of rows affected:

Course Credits ページの更新で影響を受けた行

[リストに戻る] をクリックして、単位数が変更されたコースの一覧を表示します。Click Back to List to see the list of courses with the revised number of credits.

実稼働コードでは、更新の結果が常に有効なデータになることが保証される点に注意してください。Note that production code would ensure that updates always result in valid data. ここに示した簡略化されたコードは、5 より大きい数値になるように単位数を乗算できます The simplified code shown here could multiply the number of credits enough to result in numbers greater than 5. (Credits プロパティには [Range(0, 5)] 属性があります)。更新クエリは機能しますが、無効なデータによって、5 以下の単位数を想定していたシステムの他の部分で予期しない結果が発生する可能性があります。(The Credits property has a [Range(0, 5)] attribute.) The update query would work but the invalid data could cause unexpected results in other parts of the system that assume the number of credits is 5 or less.

SQL クエリの詳細については、「Raw SQL Queries」 (生 SQL クエリ) を参照してください。For more information about raw SQL queries, see Raw SQL Queries.

SQL クエリを調べるExamine SQL queries

データベースに送信される実際の SQL クエリを確認できると役立つ場合があります。Sometimes it's helpful to be able to see the actual SQL queries that are sent to the database. ASP.NET Core の組み込みのログ記録機能は、クエリと更新の SQL を含むログを書き込むため、EF Core によって自動的に使用されます。Built-in logging functionality for ASP.NET Core is automatically used by EF Core to write logs that contain the SQL for queries and updates. このセクションでは、SQL ログの例をいくつか紹介します。In this section you'll see some examples of SQL logging.

StudentsController.cs を開き、Details メソッドで if (student == null) ステートメントにブレークポイントを設定します。Open StudentsController.cs and in the Details method set a breakpoint on the if (student == null) statement.

デバッグ モードでアプリを実行して、学生の [Details] ページに移動します。Run the app in debug mode, and go to the Details page for a student.

デバッグの出力を示す [出力] ウィンドウに移動して、クエリを確認します。Go to the Output window showing debug output, and you see the query:

Microsoft.EntityFrameworkCore.Database.Command:Information: Executed DbCommand (56ms) [Parameters=[@__id_0='?'], CommandType='Text', CommandTimeout='30']
SELECT TOP(2) [s].[ID], [s].[Discriminator], [s].[FirstName], [s].[LastName], [s].[EnrollmentDate]
FROM [Person] AS [s]
WHERE ([s].[Discriminator] = N'Student') AND ([s].[ID] = @__id_0)
ORDER BY [s].[ID]
Microsoft.EntityFrameworkCore.Database.Command:Information: Executed DbCommand (122ms) [Parameters=[@__id_0='?'], CommandType='Text', CommandTimeout='30']
SELECT [s.Enrollments].[EnrollmentID], [s.Enrollments].[CourseID], [s.Enrollments].[Grade], [s.Enrollments].[StudentID], [e.Course].[CourseID], [e.Course].[Credits], [e.Course].[DepartmentID], [e.Course].[Title]
FROM [Enrollment] AS [s.Enrollments]
INNER JOIN [Course] AS [e.Course] ON [s.Enrollments].[CourseID] = [e.Course].[CourseID]
INNER JOIN (
    SELECT TOP(1) [s0].[ID]
    FROM [Person] AS [s0]
    WHERE ([s0].[Discriminator] = N'Student') AND ([s0].[ID] = @__id_0)
    ORDER BY [s0].[ID]
) AS [t] ON [s.Enrollments].[StudentID] = [t].[ID]
ORDER BY [t].[ID]

驚くかもしれませんが、SQL は Person テーブルから最大 2 つの行 (TOP(2)) を選択します。You'll notice something here that might surprise you: the SQL selects up to 2 rows (TOP(2)) from the Person table. SingleOrDefaultAsync メソッドは、サーバー上の 1 行に解決されません。The SingleOrDefaultAsync method doesn't resolve to 1 row on the server. その理由を説明します。Here's why:

  • クエリが複数の行を返すと、メソッドは null を返します。If the query would return multiple rows, the method returns null.
  • クエリが複数の行を返すかどうかを判断するため、EF はクエリが少なくとも 2 を返すかどうかを確認する必要があります。To determine whether the query would return multiple rows, EF has to check if it returns at least 2.

[出力] ウィンドウでログ出力を取得するには、デバッグ モードを使用してブレークポイントで停止する必要はありません。Note that you don't have to use debug mode and stop at a breakpoint to get logging output in the Output window. これは単に、出力を見たいポイントでログを停止する便利な方法です。It's just a convenient way to stop the logging at the point you want to look at the output. これを行わないと、ログ記録は続行され、関心がある部分までスクロールで戻る必要があります。If you don't do that, logging continues and you have to scroll back to find the parts you're interested in.

抽象化レイヤーを作成するCreate an abstraction layer

多くの開発者は、Entity Framework で動作するコードをラップするラッパーとして、Repository パターンと Unit of Work パターンを実装するためのコードを記述します。Many developers write code to implement the repository and unit of work patterns as a wrapper around code that works with the Entity Framework. これらのパターンは、アプリケーションのデータ アクセス層とビジネス ロジック層の間に抽象化レイヤーを作成するためのものです。These patterns are intended to create an abstraction layer between the data access layer and the business logic layer of an application. これらのパターンを実装すると、データ ストアの変更からアプリケーションを隔離でき、自動化された単体テストやテスト駆動開発 (TDD) を円滑化できます。Implementing these patterns can help insulate your application from changes in the data store and can facilitate automated unit testing or test-driven development (TDD). ただし、次の複数の理由により、追加のコードを記述してこれらのパターンを実装することが、EF を使用するアプリケーションにとって最善の選択肢ではない場合もあります。However, writing additional code to implement these patterns isn't always the best choice for applications that use EF, for several reasons:

  • EF コンテキスト クラス自体が、コードをデータ ストア固有のコードから隔離します。The EF context class itself insulates your code from data-store-specific code.

  • EF コンテキスト クラスは、EF を使用して行っているデータベースの更新の unit-of-work クラスとして動作できます。The EF context class can act as a unit-of-work class for database updates that you do using EF.

  • リポジトリ コードを記述しなくても、EF には TDD を実装するための機能が含まれています。EF includes features for implementing TDD without writing repository code.

Repository パターンと Unit of Work パターンを実装する方法については、このチュートリアル シリーズの Entity Framework 5 バージョンを参照してください。For information about how to implement the repository and unit of work patterns, see the Entity Framework 5 version of this tutorial series.

Entity Framework Core は、テストに使用できる In-Memory データベース プロバイダーを実装します。Entity Framework Core implements an in-memory database provider that can be used for testing. 詳細については、InMemory を使ったテストに関するページを参照してください。For more information, see Test with InMemory.

変更の自動検出Automatic change detection

Entity Framework では、エンティティの現在の値と元の値を比較して、エンティティがどのように変更されたか (およびそれによって、どの更新プログラムをデータベースに送信する必要があるか) を判断します。The Entity Framework determines how an entity has changed (and therefore which updates need to be sent to the database) by comparing the current values of an entity with the original values. 元の値は、エンティティが照会されるかアタッチされるときに格納されます。The original values are stored when the entity is queried or attached. 変更の自動検出を行うメソッドには、次のようなものがあります。Some of the methods that cause automatic change detection are the following:

  • DbContext.SaveChangesDbContext.SaveChanges

  • DbContext.EntryDbContext.Entry

  • ChangeTracker.EntriesChangeTracker.Entries

多数のエンティティを追跡していて、これらのいずれかのメソッドをループ内で何度も呼び出す場合、ChangeTracker.AutoDetectChangesEnabled プロパティを使用して変更の自動検出を一時的にオフにすると、パフォーマンスが大幅に向上する場合があります。If you're tracking a large number of entities and you call one of these methods many times in a loop, you might get significant performance improvements by temporarily turning off automatic change detection using the ChangeTracker.AutoDetectChangesEnabled property. 次に例を示します。For example:

_context.ChangeTracker.AutoDetectChangesEnabled = false;

EF Core のソース コードと開発計画EF Core source code and development plans

Entity Framework Core のソースは、https://github.com/aspnet/EntityFrameworkCore にあります。The Entity Framework Core source is at https://github.com/aspnet/EntityFrameworkCore. EF Core リポジトリには、夜間ビルド、問題追跡、機能仕様、設計ミーティング メモ、および将来の開発のためのロードマップが含まれています。The EF Core repository contains nightly builds, issue tracking, feature specs, design meeting notes, and the roadmap for future development. バグを見つけて報告したり、投稿することができます。You can file or find bugs, and contribute.

ソース コードはオープンですが、Entity Framework Core はマイクロソフト製品として完全にサポートされています。Although the source code is open, Entity Framework Core is fully supported as a Microsoft product. Microsoft Entity Framework チームは、各リリースの品質を保証するため、受け入れる投稿を管理し、すべてのコード変更をテストしています。The Microsoft Entity Framework team keeps control over which contributions are accepted and tests all code changes to ensure the quality of each release.

既存のデータベースからのリバース エンジニアリングReverse engineer from existing database

既存のデータベースからエンティティ クラスを含むデータ モデルをリバース エンジニアリングするには、scaffold-dbcontext コマンドを使用します。To reverse engineer a data model including entity classes from an existing database, use the scaffold-dbcontext command. 入門用チュートリアルを参照してください。See the getting-started tutorial.

動的な LINQ を使ってコードを簡略化するUse dynamic LINQ to simplify code

このシリーズの 3 番目のチュートリアルでは、switchステートメントで列名をハード コーディングすることで、LINQ コードを記述する方法を示しています。The third tutorial in this series shows how to write LINQ code by hard-coding column names in a switch statement. 選択する列が 2 つの場合は正常に機能しますが、多数の列がある場合は、コードが冗長になる可能性があります。With two columns to choose from, this works fine, but if you have many columns the code could get verbose. この問題を解決するため、EF.Property メソッドを使用して、プロパティの名前を文字列として指定できます。To solve that problem, you can use the EF.Property method to specify the name of the property as a string. この方法を試すには、StudentsControllerIndex メソッドを次のコードで置き換えます。To try out this approach, replace the Index method in the StudentsController with the following code.

 public async Task<IActionResult> Index(
     string sortOrder,
     string currentFilter,
     string searchString,
     int? page)
 {
     ViewData["CurrentSort"] = sortOrder;
     ViewData["NameSortParm"] = 
         String.IsNullOrEmpty(sortOrder) ? "LastName_desc" : "";
     ViewData["DateSortParm"] = 
         sortOrder == "EnrollmentDate" ? "EnrollmentDate_desc" : "EnrollmentDate";

     if (searchString != null)
     {
         page = 1;
     }
     else
     {
         searchString = currentFilter;
     }

     ViewData["CurrentFilter"] = searchString;

     var students = from s in _context.Students
                    select s;
     
     if (!String.IsNullOrEmpty(searchString))
     {
         students = students.Where(s => s.LastName.Contains(searchString)
                                || s.FirstMidName.Contains(searchString));
     }

     if (string.IsNullOrEmpty(sortOrder))
     {
         sortOrder = "LastName";
     }

     bool descending = false;
     if (sortOrder.EndsWith("_desc"))
     {
         sortOrder = sortOrder.Substring(0, sortOrder.Length - 5);
         descending = true;
     }

     if (descending)
     {
         students = students.OrderByDescending(e => EF.Property<object>(e, sortOrder));
     }
     else
     {
         students = students.OrderBy(e => EF.Property<object>(e, sortOrder));
     }

     int pageSize = 3;
     return View(await PaginatedList<Student>.CreateAsync(students.AsNoTracking(), 
         page ?? 1, pageSize));
 }

謝辞Acknowledgments

チュートリアルを執筆してくださった、Tom Dykstra と Rick Anderson (twitter @RickAndMSFT)。Tom Dykstra and Rick Anderson (twitter @RickAndMSFT) wrote this tutorial. コードの確認をサポートし、チュートリアル用のコードの記述中に発生した問題のデバッグを支援してくれた、Rowan Miller、Diego Vega、およびその他の Entity Framework チームのメンバー。Rowan Miller, Diego Vega, and other members of the Entity Framework team assisted with code reviews and helped debug issues that arose while we were writing code for the tutorials. ASP.NET Core 2.2 用にチュートリアルの更新作業を行ってくれた、John Parente と Paul Goldman。John Parente and Paul Goldman worked on updating the tutorial for ASP.NET Core 2.2.

一般的なエラーのトラブルシューティングTroubleshoot common errors

ContosoUniversity.dll が別のプロセスによって使用されているContosoUniversity.dll used by another process

エラー メッセージError message:

'...bin\Debug\netcoreapp1.0\ContosoUniversity.dll' を書き込み用に開けません -- '別のプロセスで使用されているため、プロセスはファイル '...\bin\Debug\netcoreapp1.0\ContosoUniversity.dll' にアクセスできません。Cannot open '...bin\Debug\netcoreapp1.0\ContosoUniversity.dll' for writing -- 'The process cannot access the file '...\bin\Debug\netcoreapp1.0\ContosoUniversity.dll' because it is being used by another process.

解決方法 : Solution:

IIS express でサイトを停止します。Stop the site in IIS Express. Windows システム トレイに戻り、IIS Express を見つけてそのアイコンを右クリックし、Contoso University サイトを選択し、[サイトの停止] をクリックします。Go to the Windows System Tray, find IIS Express and right-click its icon, select the Contoso University site, and then click Stop Site.

Up メソッドと Down メソッドでコードを使用せずに移行がスキャフォールディングされるMigration scaffolded with no code in Up and Down methods

考えられる原因:Possible cause:

EF CLI コマンドは、コード ファイルを自動的に閉じて保存しません。The EF CLI commands don't automatically close and save code files. migrations add コマンドを実行するときに未保存の変更があると、EF は変更を検出しません。If you have unsaved changes when you run the migrations add command, EF won't find your changes.

解決方法 : Solution:

migrations remove コマンドを実行して、コードの変更を保存し、migrations add コマンドを再実行します。Run the migrations remove command, save your code changes and rerun the migrations add command.

データベースの更新中のエラーErrors while running database update

データが存在するデータベースでスキーマの変更を行っているときに、他のエラーが発生する場合があります。It's possible to get other errors when making schema changes in a database that has existing data. 解決できない移行エラーが発生した場合は、接続文字列のデータベース名を変更するか、データベースを削除できます。If you get migration errors you can't resolve, you can either change the database name in the connection string or delete the database. 新しいデータベースには移行するデータが存在しないため、update-database コマンドがエラーなしで完了する可能性が高くなります。With a new database, there's no data to migrate, and the update-database command is much more likely to complete without errors.

最も簡単な方法は、appsettings.json でデータベースの名前を変更することです。The simplest approach is to rename the database in appsettings.json. 次に database update を実行したときに、新しいデータベースが作成されます。The next time you run database update, a new database will be created.

SSOX でデータベースを削除するには、そのデータベースを右クリックして、[削除] をクリックしてから、[データベースの削除] ダイアログ ボックスで [既存の接続を閉じる][OK] の順にクリックします。To delete a database in SSOX, right-click the database, click Delete, and then in the Delete Database dialog box select Close existing connections and click OK.

CLI を使用してデータベースを削除するには、database drop CLI コマンドを実行します。To delete a database by using the CLI, run the database drop CLI command:

dotnet ef database drop

SQL Server インスタンスの位置を特定しているときのエラーError locating SQL Server instance

エラー メッセージ:Error Message:

SQL Server への接続を確立しているときに、ネットワーク関連またはインスタンス固有のエラーが発生しました。A network-related or instance-specific error occurred while establishing a connection to SQL Server. サーバーが見つからないかアクセスできません。The server was not found or was not accessible. インスタンス名が正しいこと、および SQL Server がリモート接続を許可するように構成されていることを確認してください。Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (プロバイダー:SQL ネットワーク インターフェイス、エラー:26 - 指定されたサーバーまたはインスタンスの位置を特定しているときにエラーが発生しました)(provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)

解決方法 : Solution:

接続文字列を確認します。Check the connection string. データベース ファイルを手動で削除した場合は、構築文字列でデータベースの名前を変更して、新しいデータベースで最初からやり直します。If you have manually deleted the database file, change the name of the database in the construction string to start over with a new database.

コードを取得するGet the code

完成したアプリケーションをダウンロードまたは表示する。Download or view the completed application.

その他の技術情報Additional resources

EF Core の詳細については、「Entity Framework Core 概要」を参照してください。For more information about EF Core, see the Entity Framework Core documentation. 書籍「Entity Framework Core in Action」もご利用いただけます。A book is also available: Entity Framework Core in Action.

Web アプリの展開方法については、「ASP.NET Core のホストと展開」を参照してください。For information on how to deploy a web app, see ASP.NET Core のホストと展開.

認証および承認などの、ASP.NET Core MVC に関連するその他のトピックについては、「ASP.NET Core の概要」を参照してください。For information about other topics related to ASP.NET Core MVC, such as authentication and authorization, see ASP.NET Core の概要.

次の手順Next steps

このチュートリアルでは、次の作業を行いました。In this tutorial, you:

  • 生 SQL クエリを実行したPerformed raw SQL queries
  • エンティティを返すクエリを呼び出したCalled a query to return entities
  • その他の型を返すクエリを呼び出したCalled a query to return other types
  • 更新クエリを呼び出したCalled an update query
  • SQL クエリを調べたExamined SQL queries
  • 抽象化レイヤーを作成したCreated an abstraction layer
  • 変更の自動検出について学習したLearned about Automatic change detection
  • EF Core のソース コードと開発計画について学習したLearned about EF Core source code and development plans
  • 動的な LINQ を使ってコードを簡略化する方法を学習したLearned how to use dynamic LINQ to simplify code

これで、ASP.NET Core MVC アプリケーションでの Entity Framework Core の使用に関するチュートリアル シリーズは終了です。This completes this series of tutorials on using the Entity Framework Core in an ASP.NET Core MVC application. ASP.NET Core と共に EF 6 を使う方法について学習する場合は、次の記事をご覧ください。If you want to learn about using EF 6 with ASP.NET Core, see the next article.