ALTER PROCEDURE [dbo].[SearchMovies]
--@Year int = null,
@CategoryIds varchar(50) = null,
@Keywords nvarchar(4000) = null,
@PageIndex int = 1,
@PageSize int = 2147483644,
@TotalRecords int = null OUTPUT
As ...
EFリポジトリ:
public class EFRepository<T> : IRepository<T> where T : BaseEntity
{
private readonly ApplicationDbContext _ctx;
private DbSet<T> entities;
string errorMessage = string.Empty;
public EFRepository(ApplicationDbContext context)
{
this._ctx = context;
entities = context.Set<T>();
}
...
public IQueryable<T> ExecuteStoredProcedureList(string commandText, params object[] parameters)
{
_ctx.Database.ExecuteSqlCommand(commandText, parameters);
return entities.FromSql(commandText, parameters);
}
}
私はこれを次のように呼びます:
var pCategoryIds = new SqlParameter()
{
ParameterName = "@CategoryIds",
Value = commaSeparatedCategoryIds,
DbType = DbType.String
};
var pKeywords = new SqlParameter()
{
ParameterName = "@Keywords",
DbType = DbType.String,
Value = name
};
var pPageIndex = new SqlParameter()
{
ParameterName = "@PageIndex",
DbType = DbType.Int32,
Value = pageIndex
};
var pPageSize = new SqlParameter()
{
ParameterName = "@PageSize",
DbType = DbType.Int32,
Value = pageSize
};
var pTotalRecords = new SqlParameter();
pTotalRecords.ParameterName = "@TotalRecords";
pTotalRecords.Direction = ParameterDirection.Output;
pTotalRecords.DbType = DbType.Int32;
var query1 = _ctx.Database.ExecuteSqlCommand("dbo.[SearchMovies] " +
"@CategoryIds, @Keywords, @PageIndex, @PageSize, @TotalRecords OUTPUT",
pCategoryIds, pKeywords, pPageIndex, pPageSize, pTotalRecords);
var query2 = _ctx.Set<MovieItem>.FromSql("dbo.[SearchMovies] " +
"@CategoryIds, @Keywords, @PageIndex, @PageSize, @TotalRecords OUTPUT",
pCategoryIds, pKeywords, pPageIndex, pPageSize, pTotalRecords);
query1
は出力pTotalRecords
を取得しますが、戻り値は取得しません。2番目のquery2
は戻り値を取得しますが、出力パラメーターは取得しません。
EF 6では、1つのコマンドで両方のアクションを実行するためにSqlQuery
を使用していましたが、EFコアで同じようにするにはどうすればよいですか?
[〜#〜]更新[〜#〜]:
一時的に、2つのクエリを実行します。1つは出力パラメーターを取得するためのもので、もう1つは結果セットのためのものです。
public IQueryable<T> ExecuteStoredProcedureList(string commandText, params object[] parameters)
{
_ctx.Database.ExecuteSqlCommand(commandText, parameters);
return entities.FromSql(commandText, parameters);
}
私はこのようなことをしました:-
-私のストアドプロシージャ:
CREATE PROCEDURE p1
AS
BEGIN
RETURN 29
END
GO
C#コード
SqlParameter[] @params =
{
new SqlParameter("@returnVal", SqlDbType.Int) {Direction = ParameterDirection.Output}
};
_stagingContext.Database.ExecuteSqlCommand("exec @returnVal=" + storedProcName, @params);
var result = @params[0].Value; //result is 29
お役に立てれば
私はいくつかのEF6コードをEF Coreに変換する作業をしており、この同じ問題に遭遇しました。 Microsoft.EntityFrameworkCoreバージョン2.1.0では、次のようにFromSql()
を使用すると、結果セットが返され、出力パラメーターが設定されます。 .ToList()
を使用して、プロシージャをすぐに強制的に実行し、結果と出力パラメータの両方を返す必要があります。
これは私のDbContextクラスのサンプルです:
private DbQuery<ExampleStoredProc_Result> ExampleStoredProc_Results { get; set; }
public IEnumerable<ExampleStoredProc_Result> RunExampleStoredProc(int firstId, out bool outputBit)
{
var outputBitParameter = new SqlParameter
{
ParameterName = "outputBit",
SqlDbType = SqlDbType.Bit,
Direction = ParameterDirection.Output
};
SqlParameter[] parameters =
{
new SqlParameter("firstId", firstId),
outputBitParameter
};
// Need to do a ToList to get the query to execute immediately
// so that we can get both the results and the output parameter.
string sqlQuery = "Exec [ExampleStoredProc] @firstId, @outputBit OUTPUT";
var results = ExampleStoredProc_Results.FromSql(sqlQuery, parameters).ToList();
outputBit = outputBitParameter.Value as bool? ?? default(bool);
return results;
}
ストアドプロシージャは次のエンティティを返します。
public class ExampleStoredProc_Result
{
public int ID { get; set; }
public string Name { get; set; }
}
これがストアドプロシージャです。
CREATE PROCEDURE ExampleStoredProc
@firstId int = 0,
@outputBit BIT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET @outputBit = 1;
SELECT @firstId AS [ID], 'first' AS [NAME]
UNION ALL
SELECT @firstId + 1 AS [ID], 'second' AS [NAME]
END
GO
うまくいけば、将来この投稿に出くわす人なら誰でも、これが役に立つと思います。