ヒント
このコンテンツは電子ブック、Azure の「ASP.NET Web Forms 開発者向け Blazor」からの抜粋です。これは .NET Docs から閲覧するか、オフラインで読める無料ダウンロードの PDF としても入手できます。
データ アクセスは、ASP.NET Web フォーム アプリのバックボーンです。 Web 用のフォームを構築している場合、そのデータはどうなりますか? Web フォームでは、データベースの操作に使用できる複数のデータ アクセス手法がありました。
- データ ソース
- ADO.NET
- エンティティ・フレームワーク(Entity Framework)
データ ソースは、Web フォーム ページに配置し、他のコントロールと同様に構成できるコントロールでした。 Visual Studio には、コントロールを構成して Web フォーム ページにバインドするためのわかりやすいダイアログ セットが用意されています。 "低コード" または "コードなし" のアプローチを利用する開発者は、Web フォームが最初にリリースされたときにこの手法を優先しました。
ADO.NET は、データベースを操作するための低レベルのアプローチです。 アプリは、対話するためのコマンド、データテーブル、データセットを使用してデータベースへの接続を作成できます。 結果は、多くのコードなしで画面上のフィールドにバインドされる可能性があります。 この方法の欠点は、ADO.NET オブジェクト (Connection
、 Command
、および DataTable
) の各セットが、データベース ベンダーによって提供されるライブラリにバインドされていたことです。 これらのコンポーネントを使用すると、コードが厳格になり、別のデータベースへの移行が困難になりました。
エンティティ・フレームワーク(Entity Framework)
Entity Framework (EF) は、.NET Foundation によって管理されるオープン ソースのオブジェクト リレーショナル マッピング フレームワークです。 .NET Framework で最初にリリースされた EF では、データベース接続、ストレージ スキーマ、相互作用のコードを生成できます。 この抽象化により、アプリのビジネス ルールに集中し、信頼されたデータベース管理者がデータベースを管理できるようになります。 .NET では、EF Core と呼ばれる EF の更新バージョンを使用できます。 EF Core は、 dotnet ef
コマンドライン ツールを使用して使用できる一連のコマンドを使用して、コードとデータベース間の相互作用を生成および維持するのに役立ちます。 データベースを操作するためのサンプルをいくつか見てみましょう。
EF コードファースト
データベースの対話の構築を簡単に開始する方法は、操作するクラス オブジェクトから始める方法です。 EF には、クラスに適したデータベース コードを生成するのに役立つツールが用意されています。 このアプローチは、"Code First" 開発と呼ばれます。 Microsoft SQL Server などのリレーショナル データベースに格納するサンプルネットショップ アプリの次の Product
クラスについて考えてみましょう。
public class Product
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[MaxLength(4000)]
public string Description { get; set; }
[Range(0, 99999,99)]
[DataType(DataType.Currency)]
public decimal Price { get; set; }
}
製品には主キーと、データベースに作成される 3 つの追加フィールドがあります。
- EF は、
Id
プロパティを規則によって主キーとして識別します。 -
Name
は、テキスト ストレージ用に構成された列に格納されます。 このプロパティを修飾する[Required]
属性は、プロパティのこの宣言された動作を強制するのに役立つnot null
制約を追加します。 -
Description
は、テキスト ストレージ用に構成された列に格納され、[MaxLength]
属性によって指定された最大長が 4,000 文字で構成されます。 データベース スキーマは、データ型MaxLength
を使用してvarchar(4000)
という名前の列で構成されます。 -
Price
プロパティは通貨として格納されます。[Range]
属性は、宣言された最小値と最大値以外のデータ ストレージを防ぐための適切な制約を生成します。
この Product
クラスを、データベースとの接続操作と変換操作を定義するデータベース コンテキスト クラスに追加する必要があります。
public class MyDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
}
MyDbContext
クラスは、Product
クラスのアクセスと翻訳を定義する 1 つのプロパティを提供します。 アプリケーションでは、Startup
クラスの ConfigureServices
メソッド内の次のエントリ (または、の代わりに builder.Services
プロパティを使用services
の適切な場所) を使用して、データベースとの対話のためにこのクラスを構成します。
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer("MY DATABASE CONNECTION STRING"));
上記のコードは、指定された接続文字列を使用して SQL Server データベースに接続します。 接続文字列は 、appsettings.json ファイル、環境変数、またはその他の構成ストレージの場所に配置し、この埋め込み文字列を適切に置き換えることができます。
次のコマンドを使用して、このクラスに適したデータベース テーブルを生成できます。
dotnet ef migrations add 'Create Product table'
dotnet ef database update
最初のコマンドでは、データベース スキーマに加える変更を、 Create Product table
という新しい EF Migration として定義します。 移行では、新しいデータベースの変更を適用および削除する方法を定義します。
適用すると、データベースに単純な Product
テーブルが作成され、データベース スキーマの管理に役立ついくつかの新しいクラスがプロジェクトに追加されます。 これらの生成されたクラスは、既定では Migrations という名前の新しいフォルダーにあります。
Product
クラスに変更を加えたり、データベースを操作する関連クラスをさらに追加したりするときは、移行の新しい名前でコマンド ライン コマンドをもう一度実行する必要があります。 このコマンドを実行すると、データベース スキーマを更新するための移行クラスの別のセットが生成されます。
EF Database First
既存のデータベースの場合は、.NET コマンド ライン ツールを使用して EF Core のクラスを生成できます。 クラスをスキャフォールディングするには、次のコマンドのバリエーションを使用します。
dotnet ef dbcontext scaffold "CONNECTION STRING" Microsoft.EntityFrameworkCore.SqlServer -c MyDbContext -t Product -t Customer
上記のコマンドは、指定した接続文字列と Microsoft.EntityFrameworkCore.SqlServer
プロバイダーを使用してデータベースに接続します。 接続されると、 MyDbContext
という名前のデータベース コンテキスト クラスが作成されます。 さらに、Product
オプションで指定されたCustomer
テーブルと-t
テーブルに対してサポート クラスが作成されます。 このコマンドには、データベースに適したクラス階層を生成するための構成オプションが多数あります。 完全なリファレンスについては、 コマンドのドキュメントを参照してください。
EF Core の詳細については、Microsoft Docs サイトを参照してください。
Web サービスとの対話
ASP.NET が最初にリリースされたとき、Web サーバーとクライアントがデータを交換する方法として SOAP サービスが推奨されていました。 その後、多くの変更が行われ、サービスとの優先される対話は、HTTP クライアントの直接の対話に移行しました。 ASP.NET Core とBlazorを使用すると、Program.csまたはHttpClient
クラスのStartup
メソッドにConfigureServices
の構成を登録できます。 HTTP エンドポイントと対話する必要がある場合は、その構成を使用します。 次の構成コードについて考えてみましょう。
// in Program.cs
builder.Services.AddHttpClient("github", client =>
{
client.BaseAddress = new Uri("http://api.github.com/");
// GitHub API versioning
client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
// GitHub requires a user-agent
client.DefaultRequestHeaders.Add("User-Agent", "BlazorWebForms-Sample");
});
GitHub からデータにアクセスする必要がある場合は常に、 github
という名前のクライアントを作成します。 クライアントはベース アドレスで構成され、要求ヘッダーが適切に設定されます。
IHttpClientFactory
ディレクティブまたはプロパティのBlazor属性を使用して、@inject
コンポーネントに[Inject]
を挿入します。 名前付きクライアントを作成し、次の構文を使用してサービスを操作します。
@inject IHttpClientFactory factory
...
@code {
protected override async Task OnInitializedAsync()
{
var client = factory.CreateClient("github");
var response = await client.GetAsync("repos/dotnet/docs/issues");
response.EnsureStatusCode();
var content = await response.Content.ReadAsStringAsync();
}
}
このメソッドは、 dotnet/docs GitHub リポジトリ内の問題のコレクションを記述する文字列を返します。 JSON 形式でコンテンツが返され、適切な GitHub 問題オブジェクトに逆シリアル化されます。 構成済みのHttpClientFactory
オブジェクトを配信するようにHttpClient
を構成するには、さまざまな方法があります。 使用するさまざまな Web サービスの名前とエンドポイントが異なる複数の HttpClient
インスタンスを構成してみてください。 この方法により、各ページでこれらのサービスとの対話が容易になります。 詳細については、「 IHttpClientFactory を使用した HTTP 要求の作成」を参照してください。
.NET