喜帳面の日記

50歳越えおやじのASP.NET MVC への挑戦日記です。

Visual Studio Express 2012 for Web でいってみる 10.ストアドプロシジャを使ってみる(2/6)

MVC4でEntity Framework経由でストアドプロシジャ(SQLServer)を動かしてみる。(2/6)

前回作成した[運送会社]のデータアクセス部分をストアドプロシジャに置き換えてみます。想定している状況は、『既存システムの部分的なMVCへの置き換えで、稼働中の既存ストアドプロシジャを使う必要がある』って状況をイメージしています。

なので、エンティティに関数としてストアドプロシジャをマッピングする手法ではありませんのであしからず。

※参考情報
エンティティ型の挿入、更新、および削除操作をストアド プロシージャにマップできます。
『変更関数をストアド プロシージャにマップする方法』
http://msdn.microsoft.com/ja-jp/library/cc716711(v=vs.90).aspx

尚、初心者が行き当たりばったりにいろいろ動かしてみたときのメモなので記載内容には勝手な解釈や誤りもあるかと思います。そのあたりのご指摘よろしくお願いします。

 


№1.ストアドプロシジャを登録する。

レコード選択用の簡単なストアドプロシジャを用意しました。こんな感じ。

CREATE PROCEDURE [dbo].[SP_GetCarriers1]
     @CarrierCDMIN  int     --コード最少
    ,@CarrierCDMAX  int     --コード最大
    ,@po_DataCount      int OUTPUT --レコード件数
    AS
    --OUTPUT PARA を初期化
    SET @po_DataCount  = 0
    -- 指定範囲のレコードを返します。
    SELECT 運送コード,運送会社,電話番号  
    FROM   dbo.運送会社
    WHERE  運送コード BETWEEN @CarrierCDMIN AND @CarrierCDMAX
    ORDER  BY  運送コード

    SET   @po_DataCount = @@rowcount --レコード件数を返します。
    

パラメータでIDの最少値と最大値を受け取り、該当のレコード群を返す。

また、対象のレコード件数をOUTPUTパラメータにセットして返します。

[運送会社]の[Index]ビューを、このストアドプロシジャを使うように変更してみます。

※ストアドプロシジャのパラメータに日本語を使うと!
今回の例で、ストアドプロシジャのパラメータに日本語、例えば[運送コードMIN]とかを使用すると、データ取得時
『指定されたパラメーター名 '運送コードMIN' は無効です。パラメーター名は英字で始まる必要があり、英字、数字、およびアンダースコアのみを含むことができます。』
こんな例外が発生します。レアケースだとは思いますが、既存のストアドプロシジャのパラメータ名に日本語を含んでいる場合は対応が必要かも。。。

 №2.ストアドプロシジャをEDM(Entity Data Model)に登録する。

1.NorthwindJ.edmxのダイアグラムでストアドプロシジャを登録する。

[Models]フォルダ内の[NorthwindJ.edmx]をクリックしてダイアログを表示します。

白地部分で右クリックし表示されるリストから[データベースからモデルを更新]を選択します。

f:id:SannomiyaNotes:20121129184124p:plain

更新ウィザードダイアログで

f:id:SannomiyaNotes:20121130110835p:plain

 [追加]タブの[ストアドプロシジャと関数]のツリーを開きターゲットのストアドプロシジャ[SP_GetCarriers1]にチェックを入れて[完了]をクリックします。

なんか「...情報を収集中です。」とかのダイアログが表示されて(一瞬なので確認できませんでした)画面が戻ってきます。ダイアグラム上では処理前となんら変わってないように見えますが、画面右下にある「モデルブラウザー」をクリックしてください。

f:id:SannomiyaNotes:20121130111305p:plain

 インポートしたストアドプロシジャが、Modelの[複合型],[関数インポート],そしてStoreの[ストアドプロシジャ/関数]の各フォルダに登録されています。また、[関数インポート]で当該ストアドプロシジャを右クリックして[編集]を選択すると[関数インポートの編集]ダイアログが表示されます。当該のストアドプロシジャは[複合型]と認識され取得したレコードコレクションは[SP_GetCarriers1_Result]となることがわかります。

尚、ストアドプロシジャが返すレコードが単一列の場合は[スカラー]、コレクションを返さない場合(パラメータのみの受け渡しのみの場合など)は[なし]に設定されます。

 

2.ストアドプロシジャの「コンテキスト?」を作成する。

1.でストアドプロシジャが返すコレクションが[SP_GetCarriers1_Result]となると書きましたが、この時点ではまだ作成されていません。

次のクラス生成作業に移る前に必ず

「ファイルの保存(edmxの保存)」を行ってください。

ファイルが保存できたら、ソリューションエクスプローラに戻って、

[Models]->[NorthwindJ.edmx]->[NorthwindJ.Context.tt]を選択し右クリック。

リストから[カスタムツールの実行]を選択します。

セキュリティ警告が出たら内容を確認して問題ないようでしたら「OK」を選択します。

画面上では変化ありませんが、

[Models]->[NorthwindJ.edmx]->[NorthwindJ.Context.tt]-->[NorthwindJ.Context.cs]を選択すると、ストアドプロシジャ呼び出しメソッドが追加されているのが確認できます。

public virtual ObjectResult SP_GetCarriers1
         (Nullable carrierCDMIN
         , Nullable carrierCDMAX
         , ObjectParameter po_DataCount)
{
    var carrierCDMINParameter = carrierCDMIN.HasValue ?
        new ObjectParameter("CarrierCDMIN", carrierCDMIN) :
        new ObjectParameter("CarrierCDMIN", typeof(int));

    var carrierCDMAXParameter = carrierCDMAX.HasValue ?
        new ObjectParameter("CarrierCDMAX", carrierCDMAX) :
        new ObjectParameter("CarrierCDMAX", typeof(int));

    return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction
    ("SP_GetCarriers1", carrierCDMINParameter, carrierCDMAXParameter, po_DataCount);
}
 

この時点ではまだ[SP_GetCarriers1_Result]が存在していないので警告線がついてます。

次に[SP_GetCarriers1_Result]の生成を行います。

[Models]->[NorthwindJ.edmx]->[NorthwindJ.tt]を選択し右クリック。

 リストから[カスタムツールの実行]を選択します。

セキュリティ警告が出たら内容を確認して問題ないようでしたら「OK」を選択します。

 [NorthwindJ.tt]の下に新しいファイル[SP_GetCarriers1_Result.cs]が生成されます。

以上でストアドプロシジャの登録作業は完了となります。次はコントローラをストアドプロシジャを呼び出すように変更します。

 


今回はここまでです。