まだ生きているようです

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
-------- : スポンサー広告 :
Pagetop

EntityFrameworkでのストアドプロシージャコール1

記憶が薄れないうちに備忘録的に書いておきます。
EntityFrameworkでストアドプロシージャを呼び出すポイントです。
(9/25に話す内容の一部になります)

ストアドプロシージャの使用には、(特にEFでは)賛否両論あるわけですが、DataBase FirstでEFを使用する場合は、DB内に既存のストアドプロシージャがあることが多いでしょう。そうした意味ではEFでの呼び出しを知っておくのもよいと思っています。

=====================================================
EFでの呼び出しは以下の2種類の手法を使用することが可能です。
  • Object Services(Ver. 4より)
  • Entity Client
(Object Servicesでの呼び出しは、Ver.4よりサポートされていますが、以前のバージョンでは完全に不可能というわけではなくて、自分でpertial classとメソッドを作成すれば可能のはずです。)

また、ストアドプロシージャコールで考えなくてはならないのは、値の受け渡しです。
以下の3種類のデータの受け渡しが可能となるのですが、それぞれEFでどう行うのかを確認してみましょう。
  • 結果セット
  • 引数
  • リターンコード

まずは、Object Servicesで考えてみたいと思います。

◆結果セット
ストアドプロシージャでクエリされた結果セットを、EFで受け取るには、以下の選択肢があります。
  • テーブルマップされたエンティティ 
    例)employeeエンティティと同じ型

  • 独自エンティティ(テーブルマップなし)
    例)employeeID 1列のみを持った結果セット

  • スカラ型
    例)nvarchar(30) 1列のみを持った結果セット

  • 複合型
    例)employeeID,Name の2列を持った結果セット

例えば、以下のようなストアドプロシージャの場合、(pubsデータベースです)
結果セットは、titleauthorテーブルから、au_idフィールドのみがselectされています。
CREATE PROCEDURE [dbo].[byroyalty] @percentage int
AS
select au_id from titleauthor
where titleauthor.royaltyper = @percentage
この場合は、テーブルマップされたエンティティでは値を受ける事が出来ないため、それ以外の3つから選ぶ事になります。

下図は、関数インポートの追加ダイアログで、ここで選択することになります。
下図では、複合型を選択していますが、複合型として選択している、byroyalty_Resultは、[列情報の取得]を実行して型を確定したのち、[新しい複合型の作成]を押下して作成したものです。

20100924_EF1.jpg

EDMの型はStringの1列なので、スカラー型でStringを選択しても良いですし、事前に概念モデルのエンティティを作っておいてもよいでしょう。

では、コードの書き方です。
using (pubsEntities db = new pubsEntities())
{
    ObjectResult<byroyalty_Result> ret = db.byroyalty(40);
    foreach (var r in ret)
    {
        Console.WriteLine(r.au_id);
    }
}
簡単ですね。ObjectResult<byroyalty_Result>型で結果セットを取得しています。

◆引数
では、今度は引数を確認してみましょう。
ただ、Input引数は、前の例で実装していますので、Output引数の実装をしてみたいと思います。

前述のストアドプロシージャを以下のように変更します。
ALTER PROCEDURE [dbo].[byroyalty]
@percentage int,
@arg nvarchar(50) output
AS
select au_id from titleauthor
where titleauthor.royaltyper = @percentage

SELECT @arg = 'テスト';

この場合、呼び出し側のコードは以下のようになります。
(ストアドプロシージャのインポートは再度行ってください)
using (pubsEntities db = new pubsEntities())
{
    ObjectParameter para = new ObjectParameter("arg", typeof(string));
    ObjectResult<byroyalty_Result> ret = db.byroyalty(40, para);
    foreach (var r in ret)
    {
        Console.WriteLine(r.au_id);
    }
    Console.WriteLine(para.Value);
}

実行した結果は以下のようになります。
20100924_EF3.jpg  

ちなみに、Output引数がある変数paraに値が正式にセットされるのは、結果セットを取得し終わった後です。

つまり以下のようにすると、上手くいきません。
using (pubsEntities db = new pubsEntities())
{
    ObjectParameter para = new ObjectParameter("arg", typeof(string));
    ObjectResult<byroyalty_Result> ret = db.byroyalty(40, para);
   
  Console.WriteLine(para.Value);

    foreach (var r in ret)
    {
        Console.WriteLine(r.au_id);
    }
}

多分ストリームから値を受け取っているせいだと思われます。直列で順番待ちになっているようです。
ADO.NETでも、結果セットを取得したDataReaderをCloseしないと、次の結果はとれませんでしたが、それと同じ感覚です。
また、もう1つの注意事項として、ストアドプロシージャ側で、Output引数のセットに、SELECTではなく、SETの使用はNGになることが挙げられます。

最後にリターンコードですが、Object Servicesでは取得することができません。
色々と工夫すればできるのかも知れませんが、デフォルトの状態では出来ないですね。

そこで、EntityClientで、呼び出しを行うことになります。(これは次回書きます。)

スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

tag : EntityFramework

2010-09-23 : EntityFramework : コメント : 0 : トラックバック : 0
Pagetop
コメントの投稿
非公開コメント

Pagetop
« next  ホーム  prev »

カレンダー

プルダウン 降順 昇順 年別

10月 | 2017年11月 | 12月
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 - -


カテゴリ

openclose

タグクラウドとサーチ

メールフォーム

名前:
メール:
件名:
本文:

プロフィール

こだかたろう

元MSの小高と申します。
(↓こんな人です。)
こんな見た目です

ずっとエバンジェリストをしていましたが、この度転身いたしました。
よろしくどうぞ。

Select Template

RSSリンクの表示

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。