sql >> Database teknologi >  >> RDS >> Oracle

Kalder Oracle lagret procedure ved hjælp af Entity Framework med output parameter?

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.




  1. Flere SET-felter ved hjælp af LOAD DATA INFILE til datoformat

  2. NYHEDER:Ny Microsoft SQL Server Native Client 18 udgivet!

  3. Sammenligning med dato i Oracle sql

  4. SQL-forespørgsel for at kontrollere, om understrengen i kolonne 1 indeholder en værdi af en anden kolonne