Dalam hal ini, Anda tidak boleh menelepon:
var query = ctx.Database.SqlQuery<CmdRegisterAssetDto>(sql, projectNameParam, countryCodeParam, locationParam, assetRegisteredParam);
Tapi malah menelepon:
var result = ctx.Database.ExecuteSqlCommand(sql, projectNameParam, countryCodeParam, locationParam, assetRegisteredParam);
Perhatikan bahwa satu-satunya perbedaan yang efektif adalah SqlQuery<CmdRegisterAssetDto>
diganti dengan ExecuteSqlCommand
. Ini juga berarti bahwa DTO tidak diperlukan. Jika tidak, kode Anda sepertinya akan berfungsi. Berikut kode asli Anda secara keseluruhan dengan perubahan yang saya sebutkan:
string projectName = "EXCO";
string location = "ANYWHERE";
string countryCode = "XX";
using (var ctx = new RAContext())
{
var projectNameParam = new OracleParameter("inProjectName", OracleDbType.Varchar2, projectName, ParameterDirection.Input);
var countryCodeParam = new OracleParameter("inCountryCode", OracleDbType.Varchar2, countryCode, ParameterDirection.Input);
var locationParam = new OracleParameter("inLocation", OracleDbType.Varchar2, location, ParameterDirection.Input);
var assetRegisteredParam = new OracleParameter("OutAssetRegistered", OracleDbType.Varchar2, ParameterDirection.Output);
var sql = "BEGIN RA.RA_RegisterAsset(:inProjectName, :inCountryCode, :inLocation, :OutAssetRegistered); END;";
var result = ctx.Database.ExecuteSqlCommand(sql, projectNameParam, countryCodeParam, locationParam, assetRegisteredParam);
assetRegistered = (string)assetRegisteredParam.Value;
}
Untuk membuktikan teori saya, saya mereproduksi perilaku nol yang Anda alami dan kemudian membuat satu perubahan itu. Itu tergantung sebentar (mungkin untuk membiarkan EF bekerja), tetapi kemudian dieksekusi dengan cepat setiap kali sesudahnya. Dalam setiap kasus, saya menemukan nilai menunggu di parameter keluar.
Jika ada orang di luar sana yang mengalami masalah, ada variasi tulisan tangan yang menangani detail skrip untuk Anda:
string projectName = "EXCO";
string location = "ANYWHERE";
string countryCode = "XX";
using (var ctx = new RAContext())
using (var cmd = ctx.Database.Connection.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "RA.RA_REGISTERASSET";
var projectNameParam = new OracleParameter("inProjectName", OracleDbType.Varchar2, projectName, ParameterDirection.Input);
var countryCodeParam = new OracleParameter("inCountryCode", OracleDbType.Varchar2, countryCode, ParameterDirection.Input);
var locationParam = new OracleParameter("inLocation", OracleDbType.Varchar2, location, ParameterDirection.Input);
var assetRegisteredParam = new OracleParameter("OutAssetRegistered", OracleDbType.Varchar2, ParameterDirection.Output);
cmd.Parameters.AddRange(new[] { projectNameParam, countryCodeParam, locationParam, assetRegisteredParam });
cmd.Connection.Open();
var result = cmd.ExecuteNonQuery();
cmd.Connection.Close();
assetRegistered = (string)assetRegisteredParam.Value;
}
Sebagai renungan, Anda secara teknis dapat menggunakan solusi asli Anda jika Anda memanggil kueri segera setelahnya (yaitu query.FirstOrDefault()
). Nilai kembalian kueri akan selalu nol, tetapi parameter keluar Anda setidaknya akan terisi. Ini karena kueri EF menggunakan eksekusi yang ditangguhkan.