I dette tilfælde bør du ikke ringe til:
var query = ctx.Database.SqlQuery<CmdRegisterAssetDto>(sql, projectNameParam, countryCodeParam, locationParam, assetRegisteredParam);
Men ring i stedet:
var result = ctx.Database.ExecuteSqlCommand(sql, projectNameParam, countryCodeParam, locationParam, assetRegisteredParam);
Bemærk, at den eneste effektive forskel er, at SqlQuery<CmdRegisterAssetDto>
blev erstattet med ExecuteSqlCommand
. Dette betyder også, at DTO'en er unødvendig. Ellers ser din kode ud til at fungere. Her er din originale kode i sin helhed med de ændringer, jeg nævnte:
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;
}
For at bevise min teori, gengav jeg den nul-adfærd, du oplever, og lavede derefter den ene ændring. Det hang lidt (sandsynligvis for at lade EF sparke i gear), men blev så hurtigt eksekveret hver gang derefter. I hvert tilfælde fandt jeg en værdi, der ventede i ud-parameteren.
Hvis nogen derude løber ind i problemer, er der en langhåndsvariation, der tager sig af scriptdetaljerne for dig:
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;
}
Som en eftertanke kunne du teknisk set gå med din originale løsning, hvis du påkaldte forespørgslen umiddelbart efter (dvs. query.FirstOrDefault()
). Returværdien af forespørgslen ville altid være null, men din ud-parameter ville i det mindste blive udfyldt. Dette skyldes, at EF-forespørgsler bruger udskudt udførelse.