計算列を使用する (C#)

作成者: Scott Mitchell

PDF のダウンロード

Microsoft SQL Server では、データベース テーブルを作成するときに、通常は同じデータベース レコードの他の値を参照する式から値が計算される計算列を定義できます。 このような値はデータベースでは読み取り専用であり、TableAdapters を使うときに特別に考慮する必要があります。 このチュートリアルでは、計算列によって発生する課題を満たす方法について説明します。

はじめに

Microsoft SQL Server では、"計算列" を使用できます。これは、通常、同じテーブル内の他の列の値を参照する式から値が計算される列です。 たとえば、時間追跡データ モデルでは、ServiceLog という名前のテーブルがあって、ServicePerformedEmployeeIDRateDuration といった列が含まれることがあります。 サービス項目ごとの支払い金額 (基準料金に期間を乗算したもの) は、Web ページまたは他のプログラム インターフェイスを使って計算できますが、この情報を報告する AmountDue という名前の列を ServiceLog テーブルに含めると便利な場合があります。 この列を通常の列として作成することもできますが、Rate または Duration 列の値が変更されたら常に更新する必要があります。 もっとよい方法は、式 Rate * Duration を使って AmountDue 列を計算列にすることです。 このようにすると、クエリで AmountDue 列が参照されるたびに、SQL Server によってその値が自動的に計算されます。

計算列の値は式によって決定されるため、このような列は読み取り専用であり、したがって INSERT または UPDATE ステートメントでそれに値を割り当てることはできません。 ただし、アドホック SQL ステートメントを使用する TableAdapter のメイン クエリの一部である計算列は、自動生成される INSERTUPDATE ステートメントに自動的に含まれます。 したがって、TableAdapter の INSERTUPDATE クエリおよび InsertCommandUpdateCommand プロパティを更新して、計算列への参照を削除する必要があります。

アドホック SQL ステートメントが使われている TableAdapter で計算列を使う場合の課題の 1 つは、TableAdapter 構成ウィザードが完了するたびに、TableAdapter の INSERTUPDATE クエリが自動的に再生成されることです。 そのため、ウィザードを再実行すると、INSERTUPDATE クエリから手動で削除した計算列が再び含まれるようになります。 ストアド プロシージャを使う TableAdapter は、この脆弱性の影響を受けませんが、ステップ 3 で取り上げる独自の問題があります。

このチュートリアルでは、Northwind データベースの Suppliers テーブルに計算列を追加してから、対応する TableAdapter を作成して、このテーブルとその計算列を操作します。 TableAdapter 構成ウィザードを使ってもカスタマイズが失われないように、アドホック SQL ステートメントの代わりにストアド プロシージャを TableAdapter で使います。

では、始めましょう。

ステップ 1: Suppliers テーブルに計算列を追加する

Northwind データベースには計算列がないため、自分で追加する必要があります。 このチュートリアルでは、連絡先の名前、役職、会社名を ContactName (ContactTitle, CompanyName) という形式で返す FullContactName という名前の計算列を、Suppliers テーブルに追加します。 この計算列は、サプライヤーに関する情報を表示するときにレポートで使われる場合があります。

最初に、サーバー エクスプローラーで Suppliers テーブルを右クリックし、コンテキスト メニューから [テーブル定義を開く] を選んで、Suppliers テーブルの定義を開きます。 これにより、テーブルの列とそのプロパティ (データ型、NULL が許可されているかどうか、など) が表示されます。 計算列を追加するには、まず、列の名前をテーブル定義に入力します。 次に、[列のプロパティ] ウィンドウの [計算列の指定] セクションの下の [(数式)] テキスト ボックスにその式を入力します (図 1 を参照)。 計算列の名前を FullContactName にして、次の式を使います。

ContactName + ' (' + CASE WHEN ContactTitle IS NOT NULL THEN 
    ContactTitle + ', ' ELSE '' END + CompanyName + ')'

SQL では + 演算子を使って文字列を連結できることに注意してください。 CASE ステートメントは、従来のプログラミング言語での条件のように使用できます。 上の式の CASE ステートメントは、次のように解釈できます。ContactTitleNULL ではない場合は、ContactTitle の値をコンマで連結して出力し、それ以外の場合は何も出力しません。 CASE ステートメントの有用性について詳しくは、SQL の CASE ステートメントに関する記事をご覧ください。

Note

ここで CASE ステートメントを使う代わりに、ISNULL(ContactTitle, '') を使うこともできます。 ISNULL(checkExpression, replacementValue) は、checkExpression が NULL でない場合はそれを返し、それ以外の場合は replacementValue を返します。 このインスタンスでは ISNULL または CASE のどちらでも機能しますが、さらに複雑なシナリオになると、CASE ステートメントの柔軟性の方が ISNULL より優ります。

この計算列を追加した後、画面は図 1 のスクリーンショットのようになります。

FullContactName という名前の計算列を Suppliers テーブルに追加する

図 1: Suppliers テーブルに FullContactName という名前の計算列を追加する (クリックするとフルサイズの画像が表示されます)

計算列の名前を指定し、式を入力した後、ツール バーの [保存] アイコンをクリックするか、Ctrl + S キーを押すか、[ファイル] メニューの [Suppliers の保存] を選んで、テーブルに対する変更を保存します。

テーブルを保存すると、Suppliers テーブルの列リストでの追加した列など、サーバー エクスプローラーが更新されます。 さらに、[(数式)] テキスト ボックスに入力した式について、不要な空白が除去され、列名が角かっこ ([]) で囲まれ、演算の順序をより明確に示すかっこが追加されて、同等の式に自動的に調整されます。

(((([ContactName]+' (')+case when [ContactTitle] IS NOT NULL 
    then [ContactTitle]+', ' else '' end)+[CompanyName])+')')

Microsoft SQL Server での計算列について詳しくは、技術ドキュメントをご覧ください。 計算列を作成する詳しい手順については、計算列の指定方法に関する記事もご覧ください。

Note

既定では、計算列はテーブルに物理的に格納されるのではなく、クエリで参照されるたびに再計算されます。 ただし、[永続化されている] チェック ボックスをオンにすると、計算列をテーブルに物理的に格納するように SQL Server に指示できます。 このようにすると、計算列に対してインデックスを作成でき、WHERE 句で計算列の値を使うクエリのパフォーマンスを向上させることができます。 詳しくは、計算列でのインデックスの作成に関する記事をご覧ください。

ステップ 2: 計算列の値を表示する

データ アクセス層の作業を始める前に、少し時間を取って FullContactName の値を見てみましょう。 サーバー エクスプローラーでテーブル名 Suppliers を右クリックして、コンテキスト メニューから [新しいクエリ] を選びます。 [クエリ] ウィンドウが表示され、クエリに含めるテーブルの選択を求められます。 Suppliers テーブルを追加して [閉じる] をクリックします。 次に、Suppliers テーブルの CompanyNameContactNameContactTitleFullContactName 列をオンにします。 最後に、ツール バーの赤い感嘆符アイコンをクリックしてクエリを実行し、結果を表示します。

図 2 に示すように、結果には、CompanyNameContactNameContactTitle 列を ContactName (ContactTitle, CompanyName) という形式で一覧表示する FullContactName が含まれます。

FullContactName は ContactName の形式 (ContactTitle、CompanyName) を使用します。

図 2: FullContactName では ContactName (ContactTitle, CompanyName) という形式が使われる (クリックするとフルサイズの画像が表示されます)

ステップ 3: データ アクセス層に SuppliersTableAdapter を追加する

アプリケーションでサプライヤー情報を操作するには、最初に DAL で TableAdapter と DataTable を作成する必要があります。 これは、前のチュートリアルで調べたのと同じ簡単な手順を使って行うのが理想的です。 ただし、計算列の使用には、説明しておいた方がよいいくつかの問題が伴います。

アドホック SQL ステートメントを使う TableAdapter を使っている場合は、TableAdapter 構成ウィザードを使って TableAdapter のメイン クエリに計算列を単に含めることができます。 ただし、このようにすると、計算列を含む INSERTUPDATE ステートメントが自動生成されます。 これらのメソッドのいずれかを実行しようとすると、"列 ColumnName を変更できません。この列は、計算列か UNION 演算子の結果のいずれかです。" というメッセージを含む SqlException 例外がスローされます。 INSERTUPDATE ステートメントは、TableAdapter の InsertCommandUpdateCommand プロパティを使って手動で調整できますが、これらのカスタマイズは、TableAdapter 構成ウィザードを再実行するたびに失われます。

アドホック SQL ステートメントを使う TableAdapter の脆弱性のため、計算列を操作するときはストアド プロシージャを使うことをお勧めします。 既存のストアド プロシージャを使っている場合は、「型指定されたデータセットの TableAdapters に既存のストアド プロシージャを使用する」チュートリアルで説明されているように、TableAdapter を構成するだけです。 一方、TableAdapter ウィザードでストアド プロシージャを自動的に作成する場合は、最初にメイン クエリから計算列を除いておくことが重要です。 メイン クエリに計算列を含めた場合、TableAdapter 構成ウィザードで、完了時に、対応するストアド プロシージャを作成できないことが示されます。 つまり、最初に計算列を含まないメイン クエリを使って TableAdapter を構成してから、対応するストアド プロシージャと TableAdapter の SelectCommand を手動で更新して、計算列を含める必要があります。 この方法は、「JOIN を使用するように TableAdapter を更新する」チュートリアルで使われているものに似ています。

このチュートリアルでは、新しい TableAdapter を追加し、ストアド プロシージャを自動的に作成します。 したがって、最初にメイン クエリから FullContactName 計算列を除いておく必要があります。

まず、~/App_Code/DAL フォルダーの NorthwindWithSprocs DataSet を開きます。 デザイナー内を右クリックし、コンテキスト メニューから新しい TableAdapter の追加を選びます。 これにより TableAdapter 構成ウィザードが起動します。 データのクエリを実行するデータベースを指定して (Web.config から NORTHWNDConnectionString)、[次へ] をクリックします。 Suppliers テーブルのクエリまたは変更を行うストアド プロシージャをまだ作成していないので、ウィザードで自動的に作成されるように [新しいストアド プロシージャを作成する] オプションを選んで、[次へ] をクリックします。

[新しいストアド プロシージャの作成] オプションを選択する

図 3: [新しいストアド プロシージャを作成する] オプションを選ぶ (クリックするとフルサイズの画像が表示されます)

その後のステップで、メイン クエリの指定を求められます。 次のクエリを入力すると、各サプライヤーの SupplierIDCompanyNameContactNameContactTitle 列が返されます。 このクエリでは計算列 (FullContactName) が意図的に除かれていることに注意してください。ステップ 4 で対応するストアド プロシージャを更新して、この列を追加します。

SELECT SupplierID, CompanyName, ContactName, ContactTitle
FROM Suppliers

メイン クエリを入力して [次へ] をクリックした後、ウィザードによって生成される 4 つのストアド プロシージャの名前を指定できます。 図 4 で示すように、これらのストアド プロシージャに Suppliers_SelectSuppliers_InsertSuppliers_UpdateSuppliers_Delete という名前を付けます。

自動生成ストアド プロシージャの名前をカスタマイズする

図 4: 自動生成されたストアド プロシージャの名前をカスタマイズする (クリックするとフルサイズの画像が表示されます)

ウィザードの次のステップでは、TableAdapter メソッドに名前を付け、データへのアクセスと更新に使うパターンを指定できます。 3 つのチェック ボックスはすべてオンのままにしますが、GetData メソッドの名前を GetSuppliers に変更します。 [完了] をクリックして、ウィザードを完了します。

GetData メソッドの名前を GetSuppliers に変更する

図 5: GetData メソッドの名前を GetSuppliers に変更する (クリックするとフルサイズの画像が表示されます)

[完了] をクリックすると、ウィザードによって 4 つのストアド プロシージャが作成され、TableAdapter および対応する DataTable が型指定された DataSet に追加されます。

ステップ 4: TableAdapter のメイン クエリに計算列を含める

ここでは、ステップ 3 で作成した TableAdapter と DataTable を更新して、FullContactName 計算列を含める必要があります。 これには、次の 2 つの手順があります。

  1. FullContactName 計算列を返すように Suppliers_Select ストアド プロシージャを更新する。
  2. 対応する FullContactName 列を含むように DataTable を更新する。

最初に、サーバー エクスプローラーに移動して、[ストアド プロシージャ] フォルダーにドリルダウンします。 Suppliers_Select ストアド プロシージャを開き、FullContactName 計算列を含むように SELECT クエリを更新します。

SELECT SupplierID, CompanyName, ContactName, ContactTitle, FullContactName
FROM Suppliers

ツール バーの [保存] アイコンをクリックするか、Ctrl + S キーを押すか、[ファイル] メニューの [Suppliers_Select の保存] オプションを選んで、ストアド プロシージャに対する変更を保存します。

次に、DataSet デザイナーに戻り、SuppliersTableAdapter を右クリックして、コンテキスト メニューから [構成] を選びます。 Suppliers_Select の列の [データ列] コレクションに FullContactName 列が含まれるようになったことに注意してください。

TableAdapter の構成ウィザードを実行して DataTable の列を更新する

図 6: TableAdapter の構成ウィザードを実行して DataTable の列を更新する (クリックするとフルサイズの画像が表示されます)

[完了] をクリックして、ウィザードを完了します。 これにより、対応する列が SuppliersDataTable に自動的に追加されます。 TableAdapter ウィザードの優れた機能によって、FullContactName 列は計算列で、したがって読み取り専用であることが検出されます。 その結果、列の ReadOnly プロパティが true に設定されます。 これを確認するには、SuppliersDataTable で列を選んで、[プロパティ] ウィンドウに移動します (図 7 を参照)。 FullContactName 列の DataTypeMaxLength プロパティも、それに応じて設定されていることに注意してください。

FullContactName 列が読み取り専用としてマークされている

図 7: FullContactName 列が読み取り専用としてマークされる (クリックするとフルサイズの画像が表示されます)

ステップ 5: GetSupplierBySupplierID メソッドを TableAdapter に追加する

このチュートリアルでは、更新可能なグリッドにサプライヤーを表示する ASP.NET ページを作成します。 過去のチュートリアルでは、ビジネス ロジック レイヤーで、DAL から 1 つのレコードを厳密に型指定された DataTable として取得し、そのプロパティを更新してから、更新された DataTable を DAL に送信して変更をデータベースに反映して、特定のレコードを更新しました。 この最初のステップ (DAL から更新対象のレコードを取得する) を実行するには、最初に GetSupplierBySupplierID(supplierID) メソッドを DAL に追加する必要があります。

DataSet デザインで SuppliersTableAdapter を右クリックして、コンテキスト メニューから [クエリの追加] オプションを選びます。 ステップ 3 で行ったように、[新しいストアド プロシージャを作成する] オプションを選んで、ウィザードで新しいストアド プロシージャを自動的に生成します (このウィザードのステップのスクリーンショットについては、図 3 を参照してください)。 このメソッドは複数の列を含むレコードを返すので、複数行を返す SELECT である SQL クエリを使うことを指定して、[次へ] をクリックします。

行を返す SELECT オプションを選択する

図 8: [複数行を返す SELECT] オプションを選ぶ (クリックするとフルサイズの画像が表示されます)

次のステップで、このメソッドに使うクエリの指定を求められます。 次のように入力します。これは、特定のサプライヤーについて、メイン クエリと同じデータ フィールドを返します。

SELECT SupplierID, CompanyName, ContactName, ContactTitle, FullContactName
FROM Suppliers
WHERE SupplierID = @SupplierID

次の画面では、自動生成されるストアド プロシージャの名前の指定を求められます。 このストアド プロシージャに Suppliers_SelectBySupplierID という名前を指定して、[次へ] をクリックします。

ストアド プロシージャに名前を付Suppliers_SelectBySupplierID

図 9: ストアド プロシージャに Suppliers_SelectBySupplierID という名前を付ける (クリックするとフルサイズの画像が表示されます)

最後に、ウィザードで TableAdapter に使うデータ アクセス パターンとメソッドの名前の指定を求められます。 どちらのチェック ボックスもオンのままにしますが、FillByGetDataBy メソッドの名前を、それぞれ FillBySupplierIDGetSupplierBySupplierID に変更します。

TableAdapter メソッドに FillBySupplierID と GetSupplierBySupplierID という名前を付けます

図 10: TableAdapter のメソッドに FillBySupplierIDGetSupplierBySupplierID の名前を付ける (クリックするとフルサイズの画像が表示されます)

[完了] をクリックして、ウィザードを完了します。

ステップ 6: ビジネス ロジック レイヤーを作成する

ステップ 1 で作成した計算列を使う ASP.NET ページを作成する前に、まず BLL に対応するメソッドを追加する必要があります。 ステップ 7 で作成する ASP.NET ページでは、ユーザーがサプライヤーを表示および編集できるようにします。 したがって、BLL では、少なくとも、すべてのサプライヤーを取得するメソッドと、特定のサプライヤーを更新する別のメソッドを提供する必要があります。

~/App_Code/BLL フォルダーに SuppliersBLLWithSprocs という名前の新しいクラス ファイルを作成して、次のコードを追加します。

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using NorthwindWithSprocsTableAdapters;
[System.ComponentModel.DataObject]
public class SuppliersBLLWithSprocs
{
    private SuppliersTableAdapter _suppliersAdapter = null;
    protected SuppliersTableAdapter Adapter
    {
        get
        {
            if (_suppliersAdapter == null)
                _suppliersAdapter = new SuppliersTableAdapter();
            return _suppliersAdapter;
        }
    }
    [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Select, true)]
    public NorthwindWithSprocs.SuppliersDataTable GetSuppliers()
    {
        return Adapter.GetSuppliers();
    }
    [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Update, true)]
    public bool UpdateSupplier(string companyName, string contactName, 
        string contactTitle, int supplierID)
    {
        NorthwindWithSprocs.SuppliersDataTable suppliers = 
            Adapter.GetSupplierBySupplierID(supplierID);
        if (suppliers.Count == 0)
            // no matching record found, return false
            return false;
        NorthwindWithSprocs.SuppliersRow supplier = suppliers[0];
        supplier.CompanyName = companyName;
        if (contactName == null) 
            supplier.SetContactNameNull(); 
        else 
            supplier.ContactName = contactName;
        if (contactTitle == null) 
            supplier.SetContactTitleNull(); 
        else 
            supplier.ContactTitle = contactTitle;
        // Update the product record
        int rowsAffected = Adapter.Update(supplier);
        // Return true if precisely one row was updated, otherwise false
        return rowsAffected == 1;
    }
}

他の BLL クラスと同様に、SuppliersBLLWithSprocsには、SuppliersTableAdapter クラスのインスタンスと、GetSuppliersUpdateSupplierの 2 つのpublic メソッドを返すprotected Adapter プロパティがあります。 GetSuppliers メソッドは、データ アクセス層の対応する GetSupplier メソッドを呼び出し、それによって返される SuppliersDataTable を返します。 UpdateSupplier メソッドは、DAL の GetSupplierBySupplierID(supplierID) メソッドを呼び出して、更新される特定のサプライヤーに関する情報を取得します。 次に、CategoryNameContactNameContactTitle プロパティを更新し、データ アクセス層の Update メソッドを呼び出して変更された SuppliersRow オブジェクトを渡して、これらの変更をデータベースにコミットします。

Note

SupplierIDCompanyName を除き、Suppliers テーブル内のすべての列で NULL 値が許可されます。 したがって、渡された contactName または contactTitle パラメーターが null の場合は、それぞれ SetContactNameNullSetContactTitleNull メソッドを使って、対応する ContactNameContactTitle プロパティを NULL データベース値に設定する必要があります。

ステップ 7: プレゼンテーション レイヤーから計算列を操作する

計算列を Suppliers テーブルに追加し、DAL と BLL をそれに応じて更新したので、FullContactName 計算列を操作する ASP.NET ページを作成する準備ができました。 AdvancedDAL フォルダー内の ComputedColumns.aspx ページを開くことから始めて、ツールボックスからデザイナーに GridView をドラッグします。 GridView の ID プロパティを Suppliers に設定し、スマート タグから SuppliersDataSource という名前の新しい ObjectDataSource にバインドします。 ステップ 6 で追加した SuppliersBLLWithSprocs クラスを使うように ObjectDataSource を構成して、[次へ] をクリックします。

SuppliersBLLWithSprocs クラスを使用するように ObjectDataSource を構成する

図 11: SuppliersBLLWithSprocs クラスを使用するように ObjectDataSource を構成する (クリックするとフルサイズの画像が表示されます)

SuppliersBLLWithSprocs クラスでは、GetSuppliersUpdateSupplier の 2 つのメソッドのみが定義されています。 これら 2 つのメソッドが [SELECT] と [UPDATE] タブでそれぞれ指定されていることを確認し、[完了] をクリックして ObjectDataSource の構成を完了します。

データ ソース構成ウィザードが完了すると、Visual Studio によって、返される各データ フィールドに対する BoundField が追加されます。 SupplierID の BoundField を削除し、CompanyNameContactNameContactTitleFullContactName の BoundField の HeaderText プロパティをそれぞれ Company、Contact Name、Title、Full Contact Name に変更します。 スマート タグから、[編集を有効にする] チェック ボックスをオンにして、GridView の組み込み編集機能を有効にします。

データ ソース ウィザードを完了すると、GridView への BoundField の追加に加えて、Visual Studio によって ObjectDataSource の OldValuesParameterFormatString プロパティが original_{0} に設定されます。 この設定を既定値の {0} に戻します。

GridView と ObjectDataSource にこれらの編集を行った後、それらの宣言マークアップは次のようになります。

<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="SupplierID" DataSourceID="SuppliersDataSource">
    <Columns>
        <asp:CommandField ShowEditButton="True" />
        <asp:BoundField DataField="CompanyName" 
            HeaderText="Company" 
            SortExpression="CompanyName" />
        <asp:BoundField DataField="ContactName" 
            HeaderText="Contact Name" 
            SortExpression="ContactName" />
        <asp:BoundField DataField="ContactTitle" 
            HeaderText="Title" 
            SortExpression="ContactTitle" />
        <asp:BoundField DataField="FullContactName" 
            HeaderText="Full Contact Name"
            SortExpression="FullContactName" 
            ReadOnly="True" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
    SelectMethod="GetSuppliers" TypeName="SuppliersBLLWithSprocs" 
        UpdateMethod="UpdateSupplier">
    <UpdateParameters>
        <asp:Parameter Name="companyName" Type="String" />
        <asp:Parameter Name="contactName" Type="String" />
        <asp:Parameter Name="contactTitle" Type="String" />
        <asp:Parameter Name="supplierID" Type="Int32" />
    </UpdateParameters>
</asp:ObjectDataSource>

次に、ブラウザーからこのページにアクセスします。 図 12 に示すように、各サプライヤーが一覧表示されるグリッドの FullContactName 列の値は、単に他の 3 つの列を ContactName (ContactTitle, CompanyName) という形式で連結したものです。

各サプライヤーがグリッドに一覧表示される

図 12: 各サプライヤーがグリッドに一覧表示される (クリックするとフルサイズの画像が表示されます)

特定のサプライヤーの [Edit] ボタンをクリックするとポストバックが発生し、その行が編集インターフェイスにレンダリングされます (図 13 を参照)。 最初の 3 つの列は、既定の編集インターフェイスである、Text プロパティがデータ フィールドの値に設定された TextBox コントロールでレンダリングされます。 しかし、FullContactName 列はテキストのままになります。 データ ソース構成ウィザードの完了時に BoundField が GridView に追加されるとき、SuppliersDataTable の対応する FullContactName 列の ReadOnly プロパティが true に設定されているため、FullContactName の BoundField の ReadOnly プロパティは true に設定されました。 ステップ 4 で説明したように、列が計算列であることを TableAdapter が検出したため、FullContactNameReadOnly プロパティは true に設定されました。

FullContactName 列は編集できません

図 13: FullContactName 列は編集できない (クリックするとフルサイズの画像が表示されます)

先に進み、編集可能な列の 1 つ以上の値を更新して、[Update] をクリックします。 FullContactName の値が変更を反映して自動的に更新されることに注意してください。

Note

現在、GridView では編集可能なフィールドに BoundField を使って、既定の編集インターフェイスが作成されています。 CompanyName フィールドは必須であるため、RequiredFieldValidator を含む TemplateField に変換される必要があります。 これは興味を持っている読者のための演習として残します。 BoundField を TemplateField に変換し、検証コントロールを追加する手順については、「編集および挿入インターフェイスに検証コントロールを追加する」チュートリアルをご覧ください。

まとめ

Microsoft SQL Server では、テーブルのスキーマを定義するときに、計算列を含めることができます。 これらの列の値は、通常、同じレコード内の他の列の値を参照する式から計算されます。 計算列の値は式に基づくため、読み取り専用であり、INSERT または UPDATE ステートメントで値を割り当てることはできません。 これにより、TableAdapter のメイン クエリで計算列を使うときに、対応する INSERTUPDATEDELETE ステートメントの自動生成が試みられる課題が発生します。

このチュートリアルでは、計算列によって発生する課題を回避するための手法について説明しました。 具体的には、TableAdapter でストアド プロシージャを使って、アドホック SQL ステートメントを使う TableAdapter に固有の脆弱性を解決しました。 TableAdapter ウィザードで新しいストアド プロシージャを作成する場合は、計算列が存在するとデータ変更ストアド プロシージャが生成されないため、メイン クエリで最初にそれを省くことが重要です。 TableAdapter が最初に構成された後で、その SelectCommand ストアド プロシージャを修正して、計算列を含めることができます。

プログラミングに満足!

著者について

7 冊の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジに取り組んでいます。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 にアクセスするか、ブログを使用して にアクセスmitchell@4GuysFromRolla.comできます。これは でhttp://ScottOnWriting.NET見つけることができます。

特別な感謝

このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのレビュー リーダーは、Hilton Geisenow と Teresa Murphy でした。 今後の MSDN の記事を確認することに関心がありますか? その場合は、 にmitchell@4GuysFromRolla.com行をドロップしてください。