チュートリアル:ASP.NET でキャッシュ アサイド スコアボードを作成する
このチュートリアルでは、Azure Cache for Redis 用の ASP.NET のクイックスタートに関する記事で作成した ContosoTeamStats ASP.NET Web アプリを更新して、Azure Cache for Redis でキャッシュ アサイド パターンを使用するスコアボードが含まれるようにします。 このサンプル アプリケーションは、データベースからチームの統計情報の一覧を表示します。 また、パフォーマンスを向上させるために、Azure Cache for Redis を使用してキャッシュに対してデータを保存および取得するさまざまな方法を例示します。 このチュートリアルを完了すると、実際にデータベースの読み取りと書き込みを行う Web アプリが完成します。この Web アプリは、Azure Cache for Redis を使って最適化され、Azure でホストされます。
このチュートリアルでは、以下の内容を学習します。
- データの保存と取得に Azure Cache for Redis を使うことでデータのスループットを高め、データベースの負荷を軽減する。
- Redis ソート済みセットを使用して上位 5 チームを取得する。
- Resource Manager テンプレートを使用してアプリケーションの Azure リソースをプロビジョニングする。
- Visual Studio を使用してアプリケーションを Azure に発行する。
Azure サブスクリプションをお持ちでない場合は、開始する前に Azure 無料アカウントを作成してください。
前提条件
このチュートリアルを完了するには、次の前提条件を満たしている必要があります。
- このチュートリアルは、Azure Cache for Redis 用の ASP.NET のクイックスタートに関する記事の続きです。 クイックスタートを完了していない場合は、先に完了してください。
- 次のワークロードを使って、Visual Studio 2019 をインストールします。
- ASP.NET および Web の開発
- Azure 開発
- SQL Server Express LocalDB または SQL Server 2017 Express エディションを使用する .NET デスクトップ開発
スコアボードをプロジェクトに追加する
チュートリアルのこのセクションでは、架空のチームの勝利、敗北、および引き分けの統計情報を報告するスコアボードを含む ContosoTeamStats プロジェクトを構成します。
Entity Framework をプロジェクトに追加する
Visual Studio で、Azure Cache for Redis 用の ASP.NET のクイックスタートに関する記事で作成した ContosoTeamStats ソリューションを開きます。
[ツール] > [NuGet パッケージ マネージャー] > [パッケージ マネージャー コンソール] を選びます。
[パッケージ マネージャー コンソール] ウィンドウで次のコマンドを実行して、EntityFramework をインストールします。
Install-Package EntityFramework
このパッケージの詳細については、EntityFramework に関する NuGet ページを参照してください。
チーム モデルを追加する
ソリューション エクスプローラーで Models フォルダーを右クリックし、 [追加] 、 [クラス] の順に選択します。
クラス名に「
Team
」と入力し、 [追加] を選択します。Team.cs ファイルの先頭にある
using
ステートメントを次のusing
ステートメントに置き換えます。using System; using System.Collections.Generic; using System.Data.Entity; using System.Data.Entity.SqlServer;
Team
クラスの定義を次のコード スニペットに置き換えます。このコード スニペットには、更新されたTeam
クラスの定義と、他の一部の Entity Framework ヘルパー クラスが含まれています。 このチュートリアルでは、Entity Framework によるコード ファースト アプローチを使用しています。 このアプローチにより、Entity Framework は、コードからデータベースを作成できます。 このチュートリアルで使用されている Entity Framework の Code First 手法の詳細については、「新しいデータベースの Code First」を参照してください。public class Team { public int ID { get; set; } public string Name { get; set; } public int Wins { get; set; } public int Losses { get; set; } public int Ties { get; set; } static public void PlayGames(IEnumerable<Team> teams) { // Simple random generation of statistics. Random r = new Random(); foreach (var t in teams) { t.Wins = r.Next(33); t.Losses = r.Next(33); t.Ties = r.Next(0, 5); } } } public class TeamContext : DbContext { public TeamContext() : base("TeamContext") { } public DbSet<Team> Teams { get; set; } } public class TeamInitializer : CreateDatabaseIfNotExists<TeamContext> { protected override void Seed(TeamContext context) { var teams = new List<Team> { new Team{Name="Adventure Works Cycles"}, new Team{Name="Alpine Ski House"}, new Team{Name="Blue Yonder Airlines"}, new Team{Name="Coho Vineyard"}, new Team{Name="Contoso, Ltd."}, new Team{Name="Fabrikam, Inc."}, new Team{Name="Lucerne Publishing"}, new Team{Name="Northwind Traders"}, new Team{Name="Consolidated Messenger"}, new Team{Name="Fourth Coffee"}, new Team{Name="Graphic Design Institute"}, new Team{Name="Nod Publishers"} }; Team.PlayGames(teams); teams.ForEach(t => context.Teams.Add(t)); context.SaveChanges(); } } public class TeamConfiguration : DbConfiguration { public TeamConfiguration() { SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy()); } }
ソリューション エクスプローラーで、Web.config をダブルクリックして開きます。
次の
connectionStrings
セクションをconfiguration
セクション内に追加します。 接続文字列の名前は、Entity Framework のデータベース コンテキスト クラスの名前と一致するTeamContext
にする必要があります。この接続文字列は、前提条件が満たされていること、および Visual Studio 2019 と共にインストールされる " .NET デスクトップ開発" ワークロードの一部である SQL Server Express LocalDB がインストールされていることを前提としています。
<connectionStrings> <add name="TeamContext" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Teams.mdf;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings>
次の例は、
configuration
セクションのconfigSections
の後に続く新しいconnectionStrings
セクションを示しています。<configuration> <configSections> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> </configSections> <connectionStrings> <add name="TeamContext" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Teams.mdf;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings> ...
TeamsController とビューを追加する
Visual Studio でプロジェクトをビルドします。
ソリューション エクスプローラーで Controllers フォルダーを右クリックし、 [追加] 、 [コントローラー] の順に選択します。
[Entity Framework を使用した、ビューがある MVC 5 コントローラー] を選択し、 [追加] を選択します。 [追加] を選択した後にエラーが発生する場合は、先にプロジェクトをビルドしたことを確認してください。
[モデル クラス] ボックスの一覧から [Team (ContosoTeamStats.Models)] を選択します。 [データ コンテキスト クラス] ボックスの一覧から [TeamContext (ContosoTeamStats.Models)] を選択します。 [コントローラー名] テキスト ボックスに「
TeamsController
」と入力します (自動的に入力されなかった場合)。 [追加] を選択してコントローラー クラスを作成し、既定のビューを追加します。ソリューション エクスプローラーで Global.asax を展開し、Global.asax.cs をダブルクリックして開きます。
ファイルの上部に次の 2 つの
using
ステートメントを、他のusing
ステートメントに続けて追加します。using System.Data.Entity; using ContosoTeamStats.Models;
Application_Start
メソッドの最後に次のコード行を追加します。Database.SetInitializer<TeamContext>(new TeamInitializer());
ソリューション エクスプローラーで
App_Start
を展開し、RouteConfig.cs
をダブルクリックします。RegisterRoutes
メソッドで、Default
ルートのcontroller = "Home"
を、次の例に示すようにcontroller = "Teams"
に置き換えます。routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Teams", action = "Index", id = UrlParameter.Optional } );
レイアウト ビューを構成する
ソリューション エクスプローラーで Views フォルダー、Shared フォルダーを順に展開し、 _Layout.cshtml をダブルクリックします。
次の例のように
title
要素の内容を変更し、My ASP.NET Application
をContoso Team Stats
に置き換えます。<title>@ViewBag.Title - Contoso Team Stats</title>
body
セクションで、Contoso Team Stats 用の次の新しいHtml.ActionLink
ステートメントを Azure Cache for Redis Test へのリンクのすぐ下に追加します。@Html.ActionLink("Contoso Team Stats", "Index", "Teams", new { area = "" }, new { @class = "navbar-brand" })`
Ctrl + F5 キーを押してアプリケーションをビルドし、実行します。 このバージョンのアプリケーションは、データベースから直接結果を読み取ります。 [Entity Framework を使用した、ビューがある MVC 5 コントローラー] スキャフォールディングによってアプリケーションに自動的に追加された [新規作成] 、 [編集] 、 [詳細] 、 [削除] の各アクションに注目してください。 このチュートリアルの次のセクションでは、Azure Cache for Redis を追加してデータへのアクセスを最適化し、アプリケーションに機能を追加します。
アプリケーションを Azure Cache for Redis 用に構成する
このセクションでは、StackExchange.Redis キャッシュ クライアントを使用して、Azure Cache for Redis インスタンスで Contoso チームの統計情報を格納したり、取得したりするようにサンプル アプリケーションを構成します。
Teams Controller へのキャッシュ接続を追加する
StackExchange.Redis クライアント ライブラリ パッケージのインストールは、クイックスタートで既に実行しています。 ローカルに使用される CacheConnection アプリ設定の構成と App Service への発行も、既に行っています。 同じクライアント ライブラリと CacheConnection情報を、TeamsController でも使用します。
ソリューション エクスプローラーで Controllers フォルダーを展開し、TeamsController.cs をダブルクリックして開きます。
次の 2 つの
using
ステートメントを TeamsController.cs に追加します。using System.Configuration; using StackExchange.Redis;
次の 2 つのプロパティを
TeamsController
クラスに追加します。// Redis Connection string info private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() => { string cacheConnection = ConfigurationManager.AppSettings["CacheConnection"].ToString(); return ConnectionMultiplexer.Connect(cacheConnection); }); public static ConnectionMultiplexer Connection { get { return lazyConnection.Value; } }
TeamsController クラスをキャッシュまたはデータベースから読み取るように更新する
このサンプルでは、データベースまたはキャッシュから、チームの統計情報を取得できます。 チームの統計情報は、シリアル化された List<Team>
としてキャッシュに格納されるほか、Redis のデータ型を使用してソート済みセットとして格納されます。 ソート済みセットから項目を取得するときは、一部または全部の項目を対象にできるほか、特定の項目を照会することもできます。 このサンプルでは、勝利数によって順位が付けられた上位 5 チームのソート済みセットを照会します。
Azure Cache for Redis を使用するために、チームの統計情報を複数の形式でキャッシュに格納する必要はありません。 このチュートリアルでは、データをキャッシュする際に使用できる各種の方法とデータ型を例示するために、複数の形式を使用しています。
TeamsController.cs
ファイルの他のusing
ステートメントの先頭に、次のusing
ステートメントを追加します。using System.Diagnostics; using Newtonsoft.Json;
現在の
public ActionResult Index()
メソッドの実装を次の実装に置き換えます。// GET: Teams public ActionResult Index(string actionType, string resultType) { List<Team> teams = null; switch(actionType) { case "playGames": // Play a new season of games. PlayGames(); break; case "clearCache": // Clear the results from the cache. ClearCachedTeams(); break; case "rebuildDB": // Rebuild the database with sample data. RebuildDB(); break; } // Measure the time it takes to retrieve the results. Stopwatch sw = Stopwatch.StartNew(); switch(resultType) { case "teamsSortedSet": // Retrieve teams from sorted set. teams = GetFromSortedSet(); break; case "teamsSortedSetTop5": // Retrieve the top 5 teams from the sorted set. teams = GetFromSortedSetTop5(); break; case "teamsList": // Retrieve teams from the cached List<Team>. teams = GetFromList(); break; case "fromDB": // Retrieve results from the database. default: teams = GetFromDB(); break; } sw.Stop(); double ms = sw.ElapsedTicks / (Stopwatch.Frequency / (1000.0)); // Add the elapsed time of the operation to the ViewBag.msg. ViewBag.msg += " MS: " + ms.ToString(); return View(teams); }
以下の 3 つのメソッドを
TeamsController
クラスに追加して、前のコード スニペットで追加した switch ステートメントにある 3 種類のアクション (playGames
、clearCache
、rebuildDB
) を実装します。PlayGames
メソッドは、あるシーズンのゲームをシミュレートすることでチームの統計情報を更新し、結果をデータベースに保存して、古くなったデータをキャッシュから消去します。void PlayGames() { ViewBag.msg += "Updating team statistics. "; // Play a "season" of games. var teams = from t in db.Teams select t; Team.PlayGames(teams); db.SaveChanges(); // Clear any cached results ClearCachedTeams(); }
RebuildDB
メソッドは、既定で存在する一連のチームでデータベースを再初期化してその統計情報を生成し、古くなったデータをキャッシュから消去します。void RebuildDB() { ViewBag.msg += "Rebuilding DB. "; // Delete and re-initialize the database with sample data. db.Database.Delete(); db.Database.Initialize(true); // Clear any cached results ClearCachedTeams(); }
ClearCachedTeams
メソッドは、キャッシュされているチームの統計情報をキャッシュから削除します。void ClearCachedTeams() { IDatabase cache = Connection.GetDatabase(); cache.KeyDelete("teamsList"); cache.KeyDelete("teamsSortedSet"); ViewBag.msg += "Team data removed from cache. "; }
キャッシュやデータベースからチームの統計情報を取得する各種の方法を実装するために、以下の 4 つのメソッドを
TeamsController
クラスに追加します。 いずれのメソッドも戻り値はList<Team>
で、それがビューに表示されます。GetFromDB
メソッドは、データベースからチームの統計情報を読み取ります。List<Team> GetFromDB() { ViewBag.msg += "Results read from DB. "; var results = from t in db.Teams orderby t.Wins descending select t; return results.ToList<Team>(); }
GetFromList
メソッドは、シリアル化されたList<Team>
としてチームの統計情報をキャッシュから読み取ります。 統計情報がキャッシュに存在しない場合は、キャッシュ ミスが発生します。 キャッシュ ミスの場合、チームの統計情報はデータベースから読み取られ、次の要求のためにキャッシュに格納されます。 このサンプルでは、JSON.NET のシリアル化を使用して、.NET オブジェクトのキャッシュへのシリアル化とキャッシュからのシリアル化を行います。 詳細については、Azure Cache for Redis における .NET オブジェクトの使用方法に関するセクションを参照してください。List<Team> GetFromList() { List<Team> teams = null; IDatabase cache = Connection.GetDatabase(); string serializedTeams = cache.StringGet("teamsList"); if (!String.IsNullOrEmpty(serializedTeams)) { teams = JsonConvert.DeserializeObject<List<Team>>(serializedTeams); ViewBag.msg += "List read from cache. "; } else { ViewBag.msg += "Teams list cache miss. "; // Get from database and store in cache teams = GetFromDB(); ViewBag.msg += "Storing results to cache. "; cache.StringSet("teamsList", JsonConvert.SerializeObject(teams)); } return teams; }
GetFromSortedSet
メソッドは、キャッシュされたソート済みセットからチームの統計情報を読み取ります。 キャッシュ ミスが発生した場合は、データベースからチームの統計情報が読み取られ、ソート済みセットとしてキャッシュに格納されます。List<Team> GetFromSortedSet() { List<Team> teams = null; IDatabase cache = Connection.GetDatabase(); // If the key teamsSortedSet is not present, this method returns a 0 length collection. var teamsSortedSet = cache.SortedSetRangeByRankWithScores("teamsSortedSet", order: Order.Descending); if (teamsSortedSet.Count() > 0) { ViewBag.msg += "Reading sorted set from cache. "; teams = new List<Team>(); foreach (var t in teamsSortedSet) { Team tt = JsonConvert.DeserializeObject<Team>(t.Element); teams.Add(tt); } } else { ViewBag.msg += "Teams sorted set cache miss. "; // Read from DB teams = GetFromDB(); ViewBag.msg += "Storing results to cache. "; foreach (var t in teams) { Console.WriteLine("Adding to sorted set: {0} - {1}", t.Name, t.Wins); cache.SortedSetAdd("teamsSortedSet", JsonConvert.SerializeObject(t), t.Wins); } } return teams; }
GetFromSortedSetTop5
メソッドは、キャッシュされたソート済みセットから上位 5 チームを読み取ります。 最初に、teamsSortedSet
キーがキャッシュに存在するかどうかをチェックします。 このキーが存在しない場合、GetFromSortedSet
メソッドが呼び出され、チームの統計情報が読み取られてキャッシュに格納されます。 次に、キャッシュされたソート済みセットから上位 5 チームを照会して返します。List<Team> GetFromSortedSetTop5() { List<Team> teams = null; IDatabase cache = Connection.GetDatabase(); // If the key teamsSortedSet is not present, this method returns a 0 length collection. var teamsSortedSet = cache.SortedSetRangeByRankWithScores("teamsSortedSet", stop: 4, order: Order.Descending); if(teamsSortedSet.Count() == 0) { // Load the entire sorted set into the cache. GetFromSortedSet(); // Retrieve the top 5 teams. teamsSortedSet = cache.SortedSetRangeByRankWithScores("teamsSortedSet", stop: 4, order: Order.Descending); } ViewBag.msg += "Retrieving top 5 teams from cache. "; // Get the top 5 teams from the sorted set teams = new List<Team>(); foreach (var team in teamsSortedSet) { teams.Add(JsonConvert.DeserializeObject<Team>(team.Element)); } return teams; }
キャッシュと連動するように Create、Edit、Delete の各メソッドを更新する
このサンプルの過程で生成されたスキャフォールディング コードには、チームの追加、編集、削除を行うメソッドが含まれています。 キャッシュ内のデータは、チームが追加、編集、削除されるたびに古くなります。 このセクションでは、キャッシュされたチームを消去するようにこれら 3 つのメソッドを変更して、キャッシュが更新されるようにします。
TeamsController
クラスのCreate(Team team)
メソッドに移動します。 次の例のように、ClearCachedTeams
メソッドの呼び出しを追加します。// POST: Teams/Create // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see https://go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create([Bind(Include = "ID,Name,Wins,Losses,Ties")] Team team) { if (ModelState.IsValid) { db.Teams.Add(team); db.SaveChanges(); // When a team is added, the cache is out of date. // Clear the cached teams. ClearCachedTeams(); return RedirectToAction("Index"); } return View(team); }
TeamsController
クラスのEdit(Team team)
メソッドに移動します。 次の例のように、ClearCachedTeams
メソッドの呼び出しを追加します。// POST: Teams/Edit/5 // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see https://go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include = "ID,Name,Wins,Losses,Ties")] Team team) { if (ModelState.IsValid) { db.Entry(team).State = EntityState.Modified; db.SaveChanges(); // When a team is edited, the cache is out of date. // Clear the cached teams. ClearCachedTeams(); return RedirectToAction("Index"); } return View(team); }
TeamsController
クラスのDeleteConfirmed(int id)
メソッドに移動します。 次の例のように、ClearCachedTeams
メソッドの呼び出しを追加します。// POST: Teams/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public ActionResult DeleteConfirmed(int id) { Team team = db.Teams.Find(id); db.Teams.Remove(team); db.SaveChanges(); // When a team is deleted, the cache is out of date. // Clear the cached teams. ClearCachedTeams(); return RedirectToAction("Index"); }
キャッシュ メソッドをチームのインデックス ビューに追加する
ソリューション エクスプローラーで、Views フォルダー、Teams フォルダーの順に展開し、Index.cshtml をダブルクリックします。
ファイルの上部付近から次の段落要素を探します。
このリンクは、新しいチームを作成します。 段落要素を以下の表に置き換えます。 この表には、新しいチームの作成、新しいシーズンのゲーム プレイ、キャッシュの消去、各種形式でのキャッシュからのチーム取得、データベースからのチームの取得、新しいサンプル データでのデータベースの再構築を行うためのアクション リンクが含まれています。
<table class="table"> <tr> <td> @Html.ActionLink("Create New", "Create") </td> <td> @Html.ActionLink("Play Season", "Index", new { actionType = "playGames" }) </td> <td> @Html.ActionLink("Clear Cache", "Index", new { actionType = "clearCache" }) </td> <td> @Html.ActionLink("List from Cache", "Index", new { resultType = "teamsList" }) </td> <td> @Html.ActionLink("Sorted Set from Cache", "Index", new { resultType = "teamsSortedSet" }) </td> <td> @Html.ActionLink("Top 5 Teams from Cache", "Index", new { resultType = "teamsSortedSetTop5" }) </td> <td> @Html.ActionLink("Load from DB", "Index", new { resultType = "fromDB" }) </td> <td> @Html.ActionLink("Rebuild DB", "Index", new { actionType = "rebuildDB" }) </td> </tr> </table>
Index.cshtml ファイルの一番下までスクロールし、次の
tr
要素を追加します。これが、ファイル内の最後のテーブルの最終行となります。<tr><td colspan="5">@ViewBag.Msg</td></tr>
この行は、
ViewBag.Msg
の値を表示します。これには、現在の操作に関する状態レポートが含まれています。ViewBag.Msg
は、前の手順のいずれかのアクション リンクを選択したときに設定されます。F6 キーを押して、プロジェクトをビルドします。
アプリをローカルで実行する
コンピューターでアプリケーションをローカルに実行して、チームをサポートするために追加されている機能を確認します。
このテストでは、アプリケーションとデータベースの両方がローカルに実行されます。 Azure Cache for Redis はローカルではありません。 Azure でリモートでホストされます。 このため、キャッシュのパフォーマンスは、データベースよりもわずかに低くなる可能性があります。 パフォーマンスを最大限に引き出すには、クライアント アプリケーションと Azure Cache for Redis インスタンスを同じ場所に置いてください。
次のセクションでは、すべてのリソースを Azure にデプロイして、キャッシュの使用によるパフォーマンスの向上を確認します。
アプリをローカルに実行するには:
Ctrl キーを押しながら F5 キーを押して アプリケーションを実行します。
ビューに追加された新しい各メソッドをテストします。 これらのテストでは、キャッシュはリモートであるため、データベースのパフォーマンスのほうがキャッシュよりもわずかに優れているはずです。
Azure に発行して実行する
アプリのデータベースをプロビジョニングする
このセクションでは、Azure でホスト中に使用されるアプリ用に SQL Database に新しいデータベースをプロビジョニングします。
Azure portal で、左上隅にある [リソースの作成] を選択します。
[新規] ページで、[データベース]>[SQL Database] の順に選択します。
新しい SQL Database で、次の設定を使用します。
設定 提案された値 説明 データベース名 ContosoTeamsDatabase 有効なデータベース名については、「Database Identifiers (データベース識別子)」を参照してください。 サブスクリプション 該当するサブスクリプション キャッシュの作成と App Service でのホストを行うために使用したのと同じサブスクリプションを選択します。 リソース グループ TestResourceGroup [既存のものを使用] を選択し、キャッシュと App Service を配置した同じリソース グループを使用します。 ソースの選択 空のデータベース 空のデータベースから始めてください。 [サーバー] で、[必要な設定の構成]>[サーバーの新規作成] を選び、次の情報を指定した後、[選択] ボタンを使用します。
設定 提案された値 説明 サーバー名 グローバルに一意の名前 有効なサーバー名については、名前付け規則と制限に関するページを参照してください。 サーバー管理者ログイン 有効な名前 有効なログイン名については、「Database Identifiers (データベース識別子)」を参照してください。 パスワード 有効なパスワード パスワードには 8 文字以上が使用され、大文字、小文字、数字、英数字以外の文字のうち、3 つのカテゴリの文字が含まれている必要があります。 場所 米国東部 キャッシュと App Service を作成したのと同じリージョンを選択します。 [ダッシュボードにピン留めする] を選択した後、 [作成] を選択して、新しいデータベースとサーバーを作成します。
新しいデータベースが作成された後、 [データベース接続文字列の表示] を選択し、ADO.NET の接続文字列をコピーします。
Azure portal で App Service に移動し、 [アプリケーションの設定] を選択し、[接続文字列] セクションの [新しい接続文字列の追加] を選択します。
Entity Framework データベースのコンテキスト クラスと一致する TeamContext という名前の新しい接続文字列を追加します。 新しいデータベースの接続文字列を値として貼り付けます。 接続文字列内の次のプレース ホルダーを置き換えたことを確認し、 [保存] を選択します。
プレースホルダー 推奨値 {your_username} 先ほど作成したサーバーのサーバー管理者ログインを使用します。 {your_password} 先ほど作成したサーバーのパスワードを使用します。 ユーザー名とパスワードをアプリケーション設定として追加しても、ユーザー名とパスワードがコードに含まれることはありません。 この方法によって、これらの資格情報を保護できます。
アプリケーションの更新を Azure に発行する
チュートリアルのこの手順では、アプリケーションの更新を Azure に発行してクラウドで実行します。
Visual Studio で ContosoTeamStats プロジェクトを右クリックし、 [発行] を選択します。
クイックスタートで作成したものと同じ発行プロファイルを使用するには、 [発行] を選択します。
発行が完了したら、Visual Studio によって、既定の Web ブラウザーでアプリが起動します。
次の表は、サンプル アプリケーションの各アクション リンクとその説明を一覧にしたものです。
アクション 説明 Create New 新しいチームを作成します。 Play Season ゲームのシーズンを再生し、チームの統計情報を更新して、キャッシュに格納されている古いチーム データがあれば消去します。 Clear Cache チームの統計情報をキャッシュから消去します。 List from Cache チームの統計情報をキャッシュから取得します。 キャッシュ ミスが発生した場合は、統計情報をデータベースから読み込んで、次回使用できるようキャッシュに保存します。 Sorted Set from Cache ソート済みセットを使用してキャッシュからチームの統計情報を取得します。 キャッシュ ミスが発生した場合は、統計情報をデータベースから読み込み、ソート済みセットを使用してキャッシュに保存します。 Top 5 Teams from Cache ソート済みセットを使用してキャッシュから上位 5 チームを取得します。 キャッシュ ミスが発生した場合は、統計情報をデータベースから読み込み、ソート済みセットを使用してキャッシュに保存します。 Load from DB チームの統計情報をデータベースから取得します。 Rebuild DB データベースを再構築し、サンプル チーム データを再度読み込みます。 Edit / Details / Delete チームの編集、詳細表示、削除を実行します。
いくつかのアクションを選択し、各種のソースからデータを取得してみてください。 それぞれの方法で、データベースとキャッシュからデータを取得するのにかかる時間の違いをよく観察してください。
リソースをクリーンアップする
チュートリアルのサンプル アプリケーションを使い終わったら、コストとリソースを節約するために Azure リソースを削除してかまいません。 すべてのリソースは同じリソース グループに含まれています。 リソース グループを削除することで、1 回の操作でそれらをまとめて削除できます。 この記事の手順では、TestResources という名前のリソース グループを使用しました。
重要
いったん削除したリソース グループを元に戻すことはできません。リソース グループとそこに存在するすべてのリソースは完全に削除されます。 間違ったリソース グループやリソースをうっかり削除しないようにしてください。 このサンプルをホスティングするリソースを、維持したいリソースが含まれている既存のリソース グループ内に作成した場合は、左側で各リソースを個別に削除できます。
Azure portal にサインインし、 [リソース グループ] を選択します。
リソース グループの名前を [フィルター項目] ボックスに入力します。
リソース グループの右側にある [...] を選択し、 [リソース グループの削除] を選択します。
リソース グループの削除の確認を求めるメッセージが表示されます。 確認のためにリソース グループの名前を入力し、 [削除] を選択します。
しばらくすると、リソース グループとそこに含まれているすべてのリソースが削除されます。