web-dev-qa-db-ja.com

ReturnValueパラメータを指定したEF ExecuteStoredCommand

レガシーコードとインターフェイスする必要がある新しいアプリケーションを作成しています:(。

私が呼び出そうとしているストアドプロシージャは、結果にRETURNを使用しています。実行して戻り値を消費しようとすると、例外が発生します。

InvalidOperationException:コマンドを実行する場合、パラメーターはデータベースのパラメーターまたは値のみでなければなりません。

ストアドプロシージャを変更して別の方法で値を返すことは望ましくありません。レガシーアプリを更新するか、ほぼ重複するストアドプロシージャを維持する必要があるためです。

従来のストアドプロシージャの概要:

DECLARE @MyID INT
INSERT INTO MyTable ...
SELECT @MyID = IDENTITY()
RETURN @MyID

私のエンティティフレームワーク/ DbContextは、上記のInvalidOperationExceptionを生成します。

 SqlParameter parm = new SqlParameter() {
    ParameterName = "@MyID",
    Direction = System.Data.ParameterDirection.ReturnValue
 };

 DbContext.Database.ExecuteSqlCommand("EXEC dbo.MyProc", parm);

ストアドプロシージャの変更を必要としないすべてのソリューションを探します。

20
KDrewiske

代わりに、ストアード・プロシージャーの戻り値を出力パラメーターに取り込むことができます。

SqlParameter parm = new SqlParameter() {  
    ParameterName = "@MyID",  
    SqlDbType = SqlDbType.Int,
    Direction = System.Data.ParameterDirection.Output  
 };  

Database.ExecuteSqlCommand("exec @MyId = dbo.MyProc", parm);

int id = (int)parm.Value;
29
Jeff Ogata

ExecuteSqlCommandを使用するためにhaveを使用しないでください。

_DbContext.Database.Connection_から基になる接続を取得し、未加工のADO.NET(CreateCommand()ExecuteNonQuery()、...)を使用することができます

2
Diego Mijelshon

私はそれが少し遅れていることを知っていますが、これは私にとってはうまくいきます:

var param = new SqlParameter("@Parameter1", txtBoxORsmth.text);

someVariable = ctx.Database.SqlQuery<int>("EXEC dbo.MyProc", param).First();
2
ProToCooL

エラーメッセージ

InvalidOperationException:コマンドを実行する場合、パラメーターはデータベースのパラメーターまたは値のみでなければなりません。

sQLParametersのparamsリストに正しいタイプ(またはコードスニペットに表示されない何か)を提供していないことを意味します。

私の場合、SQLコマンドの実行方法を変更したため、MergeOptionを削除するのを忘れていました。

0
splattne

私は上記の方法を試しましたが、この方法だけがうまくいきます( 'ToList()'関数が必要です):

 SqlParameter res = new SqlParameter()
        {
            ParameterName = "Count",
            Value=1,
            Direction = System.Data.ParameterDirection.Output
        };
db.Database.SqlQuery<object>(
         "[dbo].[GetWorkerCountBySearchConditions] @Count ,
         res
         ).ToList();
        return Convert.ToInt32(res.Value);
0
Cedric

この 拡張メソッド は、今あなたのためにすべての汚い仕事をします。 SO here )の詳細説明を参照してください。

0

これは、DBContextを使用してストアドプロシージャからintを返します。

var newId = DbContext.Database.SqlQuery<int>("EXEC dbo.MyProc @MyID = {0}", parm).First();
0
garethb

テスト用のWithパラメータの例のテーブルを作成するか、2番目のSQLクエリを自分のクエリに従って変更します。

CREATE TABLE [dbo].[Test](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](50) NOT NULL,
 CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

// ========================= ======================= ========== //

        public void Test()
        {
                  using (var db = new DbContext())
                  {
                      string sql = "dbo.MyProc";  //With Out Parameter

                  int id1 = (int)db.Database.SqlQuery<decimal>(sql).FirstOrDefault();
                  db.SaveChanges();

                  //Or

                  sql = "INSERT Test(Name) values({0}) SELECT SCOPE_IDENTITY();";  //With Parameter
                  int id2 = (int)db.Database.SqlQuery<decimal>(sql, new object[] { "Thulasi Ram.S" }).FirstOrDefault();
                  db.SaveChanges();
              }
        }
0
Thulasiram