新しいEntity Framework Coreでストアドプロシージャを使用しようとしています。 ASP.Net 5になる新しいプロジェクトをすぐに開始する必要がありますが、Entity Frameworkがその仕事に適しているかどうかはわかりません。アプリケーションが1分あたりいくつかのストアドプロシージャをトリガーするため、出力パラメーターが必要です。 EFはこれに適していますか、それともADO.Netを使用する必要がありますか?
FromSqlとdatabase.ExecuteSqlCommandを試しましたが、うまくいきませんでした。
using (AppDbContext db = factory.Create())
{
var in1 = new SqlParameter
{
ParameterName = "ParamIn1",
DbType = System.Data.DbType.Int64,
Direction = System.Data.ParameterDirection.Input
};
var in2 = new SqlParameter
{
ParameterName = "ParamIn2",
DbType = System.Data.DbType.String,
Direction = System.Data.ParameterDirection.Input
};
var out1 = new SqlParameter
{
ParameterName = "ParamOut1",
DbType = System.Data.DbType.Int64,
Direction = System.Data.ParameterDirection.Output
};
var out2 = new SqlParameter
{
ParameterName = "ParamOut2",
DbType = System.Data.DbType.String,
Direction = System.Data.ParameterDirection.Output
};
var result = db.Database.ExecuteSqlCommand("exec spTestSp", in1, in2, out1, out2);
}
動作するはずですが、コマンドステートメントにパラメータ名とOUT
キーワードも含める必要があると思います
var sql = "exec spTestSp @ParamIn1, @ParamIn2, @ParamOut1 OUT, @ParamOut2 OUT";
var result = db.Database.ExecuteSqlCommand(sql, in1, in2, out1, out2);
var out1Value = (long) out1.Value;
var out2Value = (string) out2.Value;
上記の@Nkosiと部分的に@Whistlerで説明されている解決策の完全な例。
私の例では、データベースに存在するストアドプロシージャを実行して特定のパスを取得しようとしました。
string tableName = "DocumentStore";
string path;
var in1 = new SqlParameter
{
ParameterName = "TableName",
Value = tableName,
Size = Int32.MaxValue,
DbType = System.Data.DbType.String,
Direction = System.Data.ParameterDirection.Input
};
var out1 = new SqlParameter
{
ParameterName = "Path",
DbType = System.Data.DbType.String,
Size = Int32.MaxValue,
Direction = System.Data.ParameterDirection.Output
};
//_context is DbContext Object
_context.Database.ExecuteSqlCommand("EXEC GetFileTableRootPath @TableName, @Path OUT", in1,out1);
path = out1.Value.ToString();
StoredProcedureEFCore 拡張は出力パラメーターをサポートします
すると使い方はこんな感じ
List<Model> rows = null;
ctx.LoadStoredProc("dbo.ListAll")
.AddParam("limit", 300L)
.AddParam("limitOut", out IOutParam<long> limitOut)
.Exec(r => rows = r.ToList<Model>());
long limitOutValue = limitOut.Value;
ctx.LoadStoredProc("dbo.ReturnBoolean")
.AddParam("boolean_to_return", true)
.ReturnValue(out IOutParam<bool> retParam)
.ExecNonQuery();
bool b = retParam.Value;
ctx.LoadStoredProc("dbo.ListAll")
.AddParam("limit", 1L)
.ExecScalar(out long l);