型指定された DataSet の TableAdapters に既存のストアド プロシージャを使用する (C#)
前のチュートリアルでは、TableAdapter ウィザードを使用して新しいストアド プロシージャを生成する方法について説明しました。 このチュートリアルでは、同じ TableAdapter ウィザードが既存のストアド プロシージャを操作する方法について説明します。 また、新しいストアド プロシージャをデータベースに手動で追加する方法についても説明します。
はじめに
前の チュートリアル では、アドホック SQL ステートメントではなく、ストアド プロシージャを使用してデータにアクセスするように、型指定された DataSet の TableAdapters を構成する方法について説明しました。 特に、TableAdapter ウィザードでこれらのストアド プロシージャを自動的に作成する方法について調べました。 レガシ アプリケーションを ASP.NET 2.0 に移植するとき、または既存のデータ モデルに関する ASP.NET 2.0 Web サイトを構築する場合、データベースに必要なストアド プロシージャが既に含まれている可能性があります。 または、ストアド プロシージャを手動で作成するか、ストアド プロシージャを自動生成する TableAdapter ウィザード以外のツールを使用して作成することもできます。
このチュートリアルでは、既存のストアド プロシージャを使用するように TableAdapter を構成する方法について説明します。 Northwind データベースには組み込みのストアド プロシージャのセットが少ないため、Visual Studio 環境を使用して新しいストアド プロシージャをデータベースに手動で追加するために必要な手順についても説明します。 始めましょう。
注意
トランザクション内での データベースの変更のラップ に関するチュートリアルでは、トランザクション (BeginTransaction
、 CommitTransaction
など) をサポートするメソッドを TableAdapter に追加しました。 または、ストアド プロシージャ内でトランザクションを完全に管理することもできます。これにより、データ アクセス層のコードを変更する必要はありません。 このチュートリアルでは、トランザクションのスコープ内でストアド プロシージャのステートメントを実行するために使用される T-SQL コマンドについて説明します。
手順 1: Northwind データベースへのストアド プロシージャの追加
Visual Studio を使用すると、新しいストアド プロシージャをデータベースに簡単に追加できます。 特定CategoryID
の値を持つテーブルからすべての列を返す新しいストアド プロシージャを Products
Northwind データベースに追加しましょう。 [サーバー エクスプローラー] ウィンドウで Northwind データベースを展開し、そのフォルダー (データベース ダイアグラム、テーブル、ビューなど) が表示されるようにします。 前のチュートリアルで説明したように、Stored Procedures フォルダーにはデータベースの既存のストアド プロシージャが含まれています。 新しいストアド プロシージャを追加するには、[ストアド プロシージャ] フォルダーを右クリックし、コンテキスト メニューから [新しいストアド プロシージャの追加] オプションを選択します。
図 1: ストアド プロシージャ フォルダーの Right-Click と新しいストアド プロシージャの追加 (フルサイズの画像を表示する] をクリックします)
図 1 に示すように、[新しいストアド プロシージャの追加] オプションを選択すると、Visual Studio でスクリプト ウィンドウが開き、ストアド プロシージャの作成に必要な SQL スクリプトの概要が表示されます。 このスクリプトを肉付けして実行し、その時点でストアド プロシージャがデータベースに追加されるのが私たちの仕事です。
次のスクリプトを入力します。
CREATE PROCEDURE dbo.Products_SelectByCategoryID
(
@CategoryID int
)
AS
SELECT ProductID, ProductName, SupplierID, CategoryID,
QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
ReorderLevel, Discontinued
FROM Products
WHERE CategoryID = @CategoryID
このスクリプトを実行すると、 という名前 Products_SelectByCategoryID
の Northwind データベースに新しいストアド プロシージャが追加されます。 このストアド プロシージャは、1 つの入力パラメーター (@CategoryID
型 int
) を受け取り、一致する CategoryID
値を持つそれらの製品のすべてのフィールドを返します。
この CREATE PROCEDURE
スクリプトを実行し、データベースにストアド プロシージャを追加するには、ツール バーの [保存] アイコンをクリックするか、Ctrl + S キーを押します。 その後、ストアド プロシージャ フォルダーが更新され、新しく作成されたストアド プロシージャが表示されます。 また、ウィンドウ内のスクリプトは、微妙な部分を から CREATE PROCEDURE dbo.Products_SelectProductByCategoryID
に ALTER PROCEDURE
dbo.Products_SelectProductByCategoryID
変更します。 CREATE PROCEDURE
はデータベースに新しいストアド プロシージャを追加し ALTER PROCEDURE
、既存のストアド プロシージャを更新します。 スクリプトの開始が に ALTER PROCEDURE
変更されたため、ストアド プロシージャの入力パラメーターまたは SQL ステートメントを変更し、[保存] アイコンをクリックすると、ストアド プロシージャがこれらの変更で更新されます。
図 2 は、ストアド プロシージャが保存された後の Products_SelectByCategoryID
Visual Studio を示しています。
図 2: ストアド プロシージャ Products_SelectByCategoryID
がデータベースに追加されました (フルサイズの画像を表示する をクリックします)
手順 2: 既存のストアド プロシージャを使用するように TableAdapter を構成する
ストアド プロシージャが Products_SelectByCategoryID
データベースに追加されたので、いずれかのメソッドが呼び出されたときにこのストアド プロシージャを使用するようにデータ アクセス層を構成できます。 特に、先ほど作成したストアド プロシージャをProductsTableAdapter
呼び出す型指定された DataSet の NorthwindWithSprocs
にメソッドをProducts_SelectByCategoryID
追加GetProductsByCategoryID(categoryID)
します。
DataSet を NorthwindWithSprocs
開いて開始します。 を右クリックし、[クエリの ProductsTableAdapter
追加] を選択して TableAdapter クエリ構成ウィザードを起動します。 前の チュートリアル では、TableAdapter で新しいストアド プロシージャを作成することを選択しました。 ただし、このチュートリアルでは、新しい TableAdapter メソッドを既存 Products_SelectByCategoryID
のストアド プロシージャに接続します。 そのため、ウィザードの最初の手順から [既存のストアド プロシージャを使用する] オプションを選択し、[次へ] をクリックします。
図 3: [既存のストアド プロシージャを使用する] オプションを選択します (フルサイズの画像を表示するには、ここをクリックします)
次の画面には、データベースのストアド プロシージャが設定されたドロップダウン リストが表示されます。 ストアド プロシージャを選択すると、左側に入力パラメーターが表示され、右側に返されるデータ フィールド (存在する場合) が一覧表示されます。 一覧からストアド プロシージャを Products_SelectByCategoryID
選択し、[次へ] をクリックします。
図 4: ストアド プロシージャを Products_SelectByCategoryID
選択する (フルサイズの画像を表示する場合はクリックします)
次の画面では、ストアド プロシージャによって返されるデータの種類が確認され、ここでの回答によって TableAdapter s メソッドによって返される型が決まります。 たとえば、表形式のデータが返されることを示す場合、メソッドはストアド プロシージャによって返されるレコードが設定されたインスタンスを返 ProductsDataTable
します。 これに対し、このストアド プロシージャから 1 つの値が返されることを示す場合、TableAdapter は、ストアド プロシージャによって返される最初のレコードの最初の列の値が割り当てられた を返 object
します。
ストアド プロシージャは特定の Products_SelectByCategoryID
カテゴリに属するすべての製品を返すので、最初の回答 (表形式データ) を選択し、[次へ] をクリックします。
図 5: ストアド プロシージャから表形式データが返されることを示す (フルサイズの画像を表示する場合は、ここをクリックします)
残っているのは、使用するメソッド パターンの後にこれらのメソッドの名前が続く方法を示すものです。 [DataTable の塗りつぶし] オプションと [DataTable を返す] オプションの両方をオンのままにしますが、メソッドの名前は と GetProductsByCategoryID
にFillByCategoryID
変更します。 次に、[次へ] をクリックして、ウィザードが実行するタスクの概要を確認します。 すべてが正しければ、[完了] をクリックします。
図 6: メソッドに名前を付け FillByCategoryID
、 GetProductsByCategoryID
(フルサイズの画像を表示する場合はクリックします)
注意
先ほど作成した TableAdapter メソッド と は、FillByCategoryID
型の入力パラメーターを必要としますint
。GetProductsByCategoryID
この入力パラメーター値は、その @CategoryID
パラメーターを使用してストアド プロシージャに渡されます。 ストアド プロシージャのパラメーターを Products_SelectByCategory
変更する場合は、これらの TableAdapter メソッドのパラメーターも更新する必要があります。 前のチュートリアルで説明したように、これは、パラメーター コレクションからパラメーターを手動で追加または削除するか、TableAdapter ウィザードを再実行するという 2 つの方法のいずれかで行うことができます。
手順 3: メソッドをGetProductsByCategoryID(categoryID)
BLL に追加する
DAL メソッドが GetProductsByCategoryID
完了したら、次の手順は、ビジネス ロジック層でこのメソッドへのアクセスを提供することです。 クラス ファイルを ProductsBLLWithSprocs
開き、次のメソッドを追加します。
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Select, false)]
public NorthwindWithSprocs.ProductsDataTable GetProductByCategoryID(int categoryID)
{
return Adapter.GetProductsByCategoryID(categoryID);
}
この BLL メソッドは、 メソッドから返された をProductsDataTable
単にGetProductsByCategoryID
ProductsTableAdapter
返します。 属性は DataObjectMethodAttribute
、ObjectDataSource のデータ ソースの構成ウィザードで使用されるメタデータを提供します。 特に、このメソッドは SELECT タブのドロップダウン リストに表示されます。
手順 4: カテゴリ別に製品を表示する
新しく追加 Products_SelectByCategoryID
されたストアド プロシージャと対応する DAL メソッドと BLL メソッドをテストするには、DropDownList と GridView を含む ASP.NET ページを作成します。 DropDownList にはデータベース内のすべてのカテゴリが一覧表示され、GridView には選択したカテゴリに属する製品が表示されます。
注意
前のチュートリアルで DropDownLists を使用してマスター/詳細インターフェイスを作成しました。 このようなマスター/詳細レポートの実装の詳細については、「 Master/Detail Filtering With a DropDownList 」チュートリアルを参照してください。
フォルダー内のExistingSprocs.aspx
ページをAdvancedDAL
開き、[ツールボックス] から [DropDownList] をDesignerにドラッグします。 DropDownList の ID
プロパティを に Categories
設定し、そのプロパティを AutoPostBack
に true
設定します。 次に、そのスマート タグから、DropDownList を という名前 CategoriesDataSource
の新しい ObjectDataSource にバインドします。 ObjectDataSource を構成して、クラスの GetCategories
メソッドからデータをCategoriesBLL
取得します。 [更新]、[挿入]、および [削除] タブのドロップダウン リストを に設定します (なし)。
図 7: クラス s GetCategories
メソッドからデータをCategoriesBLL
取得する (フルサイズの画像を表示する場合はクリックします)
図 8: UPDATE、INSERT、DELETE タブの Drop-Down Lists を (なし) に設定します (フルサイズの画像を表示する場合はクリックします)
ObjectDataSource ウィザードが完了したら、DropDownList を構成してデータ フィールドをCategoryName
表示し、各 の フィールドを としてValue
使用CategoryID
しますListItem
。
この時点で、DropDownList と ObjectDataSource の宣言型マークアップは次のようになります。
<asp:DropDownList ID="Categories" runat="server" AutoPostBack="True"
DataSourceID="CategoriesDataSource" DataTextField="CategoryName"
DataValueField="CategoryID">
</asp:DropDownList>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>
次に、GridView をDesignerにドラッグし、DropDownList の下に配置します。 GridView を ID
に ProductsByCategory
設定し、スマート タグから という名前 ProductsByCategoryDataSource
の新しい ObjectDataSource にバインドします。 クラスを ProductsByCategoryDataSource
使用するように ObjectDataSource を ProductsBLLWithSprocs
構成し、 メソッドを使用してデータを GetProductsByCategoryID(categoryID)
取得します。 この GridView はデータの表示にのみ使用されるため、UPDATE タブ、INSERT タブ、DELETE タブのドロップダウン リストを (None) に設定し、[次へ] をクリックします。
図 9: クラスを使用するように ObjectDataSource を構成する ProductsBLLWithSprocs
(クリックするとフルサイズの画像が表示されます)
図 10: メソッドからデータを取得します GetProductsByCategoryID(categoryID)
(クリックするとフルサイズの画像が表示されます)
[SELECT] タブで選択したメソッドはパラメーターを必要とするため、ウィザードの最後の手順でパラメーターのソースの入力を求められます。 [パラメーター ソース] ドロップダウン リストを [コントロール] に設定し、[ControlID] ドロップダウン リストからコントロールを選択 Categories
します。 [完了] をクリックしてウィザードを終了します。
図 11: パラメーターのCategories
ソースとして DropDownList を使用する (フルサイズのcategoryID
画像を表示する をクリックします)
ObjectDataSource ウィザードが完了すると、Visual Studio によって各製品データ フィールドに BoundFields と CheckBoxField が追加されます。 必要に応じて、これらのフィールドを自由にカスタマイズできます。
ブラウザーからページにアクセスします。 ページにアクセスすると、飲料カテゴリが選択され、グリッドに対応する製品が一覧表示されます。 図 12 に示すように、ドロップダウン リストを別のカテゴリに変更すると、ポストバックが発生し、新しく選択したカテゴリの製品でグリッドが再読み込みされます。
図 12: [生産] カテゴリの製品が表示されます (クリックするとフルサイズの画像が表示されます)
手順 5: トランザクションのスコープ内でストアド プロシージャのステートメントをラップする
トランザクション内の データベース変更のラップ チュートリアルでは、トランザクションのスコープ内で一連のデータベース変更ステートメントを実行する手法について説明しました。 トランザクションの傘下で実行された変更は、すべて成功するかすべて失敗するかのどちらかであり、原子性が保証されることを思い出してください。 トランザクションを使用する方法は次のとおりです。
- 名前空間のクラスを使用して、
System.Transactions
- データ アクセス層で、 などの
SqlTransaction
ADO.NET クラスを使用する - ストアド プロシージャ内で T-SQL トランザクション コマンドを直接追加する
トランザクション内でのデータベースの変更のラップに関するチュートリアルでは、DAL の ADO.NET クラスを使用しました。 このチュートリアルの残りの部分では、ストアド プロシージャ内から T-SQL コマンドを使用してトランザクションを管理する方法について説明します。
トランザクションを手動で開始、コミット、ロールバックするための 3 つの主要な SQL コマンドは BEGIN TRANSACTION
、それぞれ 、 COMMIT TRANSACTION
、および ROLLBACK TRANSACTION
です。 ADO.NET アプローチと同様に、ストアド プロシージャ内からトランザクションを使用する場合は、次のパターンを適用する必要があります。
- トランザクションの開始を示します。
- トランザクションを構成する SQL ステートメントを実行します。
- 手順 2 のいずれかのステートメントでエラーが発生した場合は、トランザクションをロールバックします
- 手順 2 のすべてのステートメントがエラーなしで完了した場合は、トランザクションをコミットします。
このパターンは、次のテンプレートを使用して T-SQL 構文で実装できます。
BEGIN TRY
BEGIN TRANSACTION -- Start the transaction
... Perform the SQL statements that makeup the transaction ...
-- If we reach here, success!
COMMIT TRANSACTION
END TRY
BEGIN CATCH
-- Whoops, there was an error
ROLLBACK TRANSACTION
-- Raise an error with the
-- details of the exception
DECLARE @ErrMsg nvarchar(4000),
@ErrSeverity int
SELECT @ErrMsg = ERROR_MESSAGE(),
@ErrSeverity = ERROR_SEVERITY()
RAISERROR(@ErrMsg, @ErrSeverity, 1)
END CATCH
テンプレートは、2005 年SQL Server新しいコンストラクトであるブロックを定義TRY...CATCH
することから始まります。 C# のブロックと try...catch
同様に、SQL TRY...CATCH
ブロックは ブロック内の ステートメントを TRY
実行します。 いずれかのステートメントでエラーが発生した場合、制御はすぐに ブロックに CATCH
転送されます。
トランザクションを構成する SQL ステートメントを実行するエラーがない場合、ステートメントは COMMIT TRANSACTION
変更をコミットしてトランザクションを完了します。 ただし、ステートメントの 1 つでエラーが発生した場合、 ブロック内CATCH
の はROLLBACK TRANSACTION
、トランザクションの開始前にデータベースをその状態に戻します。 また、このストアド プロシージャでは RAISERROR コマンドを使用してエラーが発生します。これにより SqlException
、 がアプリケーションで発生します。
注意
TRY...CATCH
ブロックは 2005 年SQL Server新しいため、以前のバージョンの Microsoft SQL Serverを使用している場合、上記のテンプレートは機能しません。
具体的な例を見てみましょう。 テーブルと Products
テーブルの間Categories
には外部キー制約が存在します。つまり、テーブル内の各CategoryID
フィールドはテーブル内Products
のCategoryID
値にマップするCategories
必要があります。 製品が関連付けられているカテゴリの削除など、この制約に違反するアクションは、外部キー制約違反になります。 これを確認するには、「バイナリ データの操作」セクション (~/BinaryData/UpdatingAndDeleting.aspx
) の「既存のバイナリ データの更新と削除」の例を再検討してください。 このページには、システム内の各カテゴリと [編集] ボタンと [削除] ボタンが一覧表示されますが (図 13 を参照)、関連する製品 (飲料など) を持つカテゴリを削除しようとすると、外部キー制約違反が原因で削除が失敗します (図 14 を参照)。
図 13: 各カテゴリは、編集ボタンと削除ボタンを含む GridView に表示されます (フルサイズの画像を表示する をクリックします)
図 14: 既存の製品があるカテゴリを削除できません (クリックするとフルサイズの画像が表示されます)
ただし、関連する製品があるかどうかに関係なく、カテゴリの削除を許可するとします。 製品を含むカテゴリを削除する場合は、既存の製品も削除するとします (ただし、別のオプションとして、製品 CategoryID
の値を に NULL
設定するだけです)。 この機能は、外部キー制約の連鎖ルールを使用して実装できます。 または、入力パラメーターを受け入れるストアド プロシージャを @CategoryID
作成し、呼び出されると、関連付けられているすべての製品と指定したカテゴリを明示的に削除することもできます。
このようなストアド プロシージャでの最初の試行は、次のようになります。
CREATE PROCEDURE dbo.Categories_Delete
(
@CategoryID int
)
AS
-- First, delete the associated products...
DELETE FROM Products
WHERE CategoryID = @CategoryID
-- Now delete the category
DELETE FROM Categories
WHERE CategoryID = @CategoryID
これは間違いなく関連する製品とカテゴリを削除しますが、トランザクションの傘の下では削除されません。 特定@CategoryID
の値の削除を禁止する他の外部キー制約Categories
があるとします。 問題は、そのような場合、カテゴリの削除を試みる前に、すべての製品が削除されることです。 結果として、このようなカテゴリの場合、このストアド プロシージャは、他のテーブルに関連するレコードが残っているため、カテゴリが残っている間にすべての製品を削除します。
ただし、ストアド プロシージャがトランザクションのスコープ内でラップされた場合、テーブルへの Products
削除は、 で削除が失敗した場合に Categories
ロールバックされます。 次のストアド プロシージャ スクリプトでは、トランザクションを使用して、2 つの DELETE
ステートメント間の原子性を確保します。
CREATE PROCEDURE dbo.Categories_Delete
(
@CategoryID int
)
AS
BEGIN TRY
BEGIN TRANSACTION -- Start the transaction
-- First, delete the associated products...
DELETE FROM Products
WHERE CategoryID = @CategoryID
-- Now delete the category
DELETE FROM Categories
WHERE CategoryID = @CategoryID
-- If we reach here, success!
COMMIT TRANSACTION
END TRY
BEGIN CATCH
-- Whoops, there was an error
ROLLBACK TRANSACTION
-- Raise an error with the
-- details of the exception
DECLARE @ErrMsg nvarchar(4000),
@ErrSeverity int
SELECT @ErrMsg = ERROR_MESSAGE(),
@ErrSeverity = ERROR_SEVERITY()
RAISERROR(@ErrMsg, @ErrSeverity, 1)
END CATCH
ストアド プロシージャを Northwind データベースに追加 Categories_Delete
します。 データベースにストアド プロシージャを追加する手順については、手順 1 に戻るを参照してください。
手順 6: を更新するCategoriesTableAdapter
データベースにストアド プロシージャを Categories_Delete
追加しましたが、DAL は現在、アドホック SQL ステートメントを使用して削除を実行するように構成されています。 を更新 CategoriesTableAdapter
し、代わりにストアド プロシージャを使用するように指示する Categories_Delete
必要があります。
注意
このチュートリアルの前半では、DataSet を NorthwindWithSprocs
使用していました。 ただし、DataSet には 1 つのエンティティ () のみが含まれており、 ProductsDataTable
カテゴリを操作する必要があります。 したがって、このチュートリアルの残りの部分では、Data Access Layer の作成チュートリアルで最初にNorthwind
作成した DataSet を参照しています。
Northwind DataSet を開き、 をCategoriesTableAdapter
選択し、プロパティ ウィンドウに移動します。 プロパティ ウィンドウには、TableAdapter で使用される 、UpdateCommand
、DeleteCommand
、、SelectCommand
およびその名前と接続情報が一覧表示InsertCommand
されます。 プロパティを DeleteCommand
展開して詳細を表示します。 図 15 に示すように、 DeleteCommand
プロパティ CommandType
は Text に設定され、プロパティ内の CommandText
テキストをアドホック SQL クエリとして送信するように指示されます。
図 15: [プロパティ] CategoriesTableAdapter
ウィンドウでプロパティを表示するには、Designerの を選択します
これらの設定を変更するには、プロパティ ウィンドウの (DeleteCommand) テキストを選択し、ドロップダウン リストから [(新規)] を選択します。 これにより、、CommandType
、および Parameters
プロパティの設定がCommandText
クリアされます。 次に、 プロパティを CommandType
にStoredProcedure
設定し、 (dbo.Categories_Delete
) のストアド プロシージャの名前をCommandText
入力します。 プロパティを必ずこの順序で入力する場合は、最初に を CommandType
、次に CommandText
- Visual Studio によって Parameters コレクションが自動的に設定されます。 これらのプロパティをこの順序で入力しない場合は、[パラメーター コレクション] エディターを使用してパラメーターを手動で追加する必要があります。 どちらの場合も、Parameters プロパティの省略記号をクリックして Parameters コレクション エディターを表示し、正しいパラメーター設定が変更されたことを確認することをお読みください (図 16 を参照)。 ダイアログ ボックスにパラメーターが表示されない場合は、パラメーターを @CategoryID
手動で追加します (パラメーターを @RETURN_VALUE
追加する必要はありません)。
図 16: パラメーター設定が正しいことを確認する
DAL が更新されると、カテゴリを削除すると、関連付けられているすべての製品が自動的に削除され、トランザクションの傘の下で削除されます。 これを確認するには、[既存のバイナリ データの更新と削除] ページに戻り、いずれかのカテゴリの [削除] ボタンをクリックします。 マウスを 1 回クリックすると、カテゴリとそれに関連付けられているすべての製品が削除されます。
注意
選択したカテゴリと共に Categories_Delete
多数の製品を削除するストアド プロシージャをテストする前に、データベースのバックアップ コピーを作成することが賢明な場合があります。 でApp_Data
データベースをNORTHWND.MDF
使用している場合は、Visual Studio を閉じて、 の MDF ファイルと LDF ファイルを他のApp_Data
フォルダーにコピーします。 機能をテストしたら、Visual Studio を閉じ、現在の MDF ファイルと LDF ファイルをバックアップ コピーに App_Data
置き換えることで、データベースを復元できます。
まとめ
TableAdapter ウィザードではストアド プロシージャが自動的に生成されますが、このようなストアド プロシージャが既に作成されているか、手動で作成するか、代わりに他のツールで作成したい場合があります。 このようなシナリオに対応するために、TableAdapter は既存のストアド プロシージャを指すように構成することもできます。 このチュートリアルでは、Visual Studio 環境を使用してデータベースにストアド プロシージャを手動で追加する方法と、TableAdapter のメソッドをこれらのストアド プロシージャに接続する方法について説明しました。 また、ストアド プロシージャ内からトランザクションを開始、コミット、ロールバックするために使用される T-SQL コマンドとスクリプト パターンについても調べました。
幸せなプログラミング!
著者について
7 冊の ASP/ASP.NET 書籍の著者であり、 4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジと協力しています。 Scott は独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズ・ティーチ・自分自身 ASP.NET 24時間で2.0です。 にアクセスmitchell@4GuysFromRolla.comすることも、ブログを介して アクセスすることもできます。これは でhttp://ScottOnWriting.NET確認できます。
特別な感謝
このチュートリアル シリーズは、多くの役立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、Hilton Geisenow、S ren Jacob Lauritsen、Toria Murphy でした。 今後の MSDN 記事の確認に関心がありますか? その場合は、 に行mitchell@4GuysFromRolla.comをドロップしてください。
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示