sql >> Databasteknik >  >> RDS >> Oracle

Anropa Oracles lagrade procedur med Entity Framework med utdataparameter?

I det här fallet bör du inte ringa:

var query = ctx.Database.SqlQuery<CmdRegisterAssetDto>(sql, projectNameParam, countryCodeParam, locationParam, assetRegisteredParam);

Men istället ring:

var result = ctx.Database.ExecuteSqlCommand(sql, projectNameParam, countryCodeParam, locationParam, assetRegisteredParam);

Observera att den enda effektiva skillnaden är att SqlQuery<CmdRegisterAssetDto> ersattes med ExecuteSqlCommand . Detta betyder också att DTO är onödigt. Annars ser din kod ut som att den borde fungera. Här är din ursprungliga kod i sin helhet med de ändringar jag nämnde:

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;
}

För att bevisa min teori, återskapade jag det nollbeteende som du upplever och gjorde sedan den där förändringen. Det hängde ett tag (förmodligen för att låta EF sparka i växel), men exekverades sedan snabbt varje gång därefter. I varje fall hittade jag ett värde som väntade i parametern ut.

Om någon där ute stöter på problem finns det en variant som tar hand om skriptdetaljerna åt 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 kan du tekniskt sett gå med din ursprungliga lösning om du anropade frågan omedelbart efter (dvs. query.FirstOrDefault() ). Returvärdet för frågan skulle alltid vara null, men din out-parameter skulle åtminstone fyllas i. Detta beror på att EF-frågor använder uppskjuten exekvering.




  1. Dataintegritet och prestandaöverväganden i MySQL semisynkron replikering

  2. FATAL:kunde inte komma åt den privata nyckelfilen /etc/ssl/private/ssl-cert-snakeoil.key:Tillstånd nekad

  3. python MySQLDb-inlägg med förberedda uttalanden

  4. Hur ändrar man en sträng till ett datum under import med Sequel Pro?