sql >> Databáze >  >> RDS >> Oracle

Volání uložené procedury Oracle pomocí Entity Framework s výstupním parametrem?

V tomto případě byste neměli volat:

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

Ale místo toho volejte:

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

Všimněte si, že jediný účinný rozdíl je v tom, že SqlQuery<CmdRegisterAssetDto> byl nahrazen ExecuteSqlCommand . To také znamená, že DTO je zbytečné. Jinak váš kód vypadá, že by měl fungovat. Zde je váš původní kód v celém rozsahu se změnami, které jsem zmínil:

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

Abych dokázal svou teorii, reprodukoval jsem nulové chování, které zažíváte, a pak jsem provedl jednu změnu. Chvíli to viselo (pravděpodobně aby EF zařadil rychlost), ale pak se to pokaždé rychle provedlo. V každém případě jsem našel hodnotu čekající v parametru out.

Pokud by se někdo dostal do potíží, existuje dlouhá varianta, která se o detaily skriptování postará za vás:

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

Jako dodatečný nápad byste technicky mohli použít své původní řešení, pokud byste dotaz vyvolali bezprostředně po (tj. query.FirstOrDefault() ). Vrácená hodnota dotazu by byla vždy null, ale váš parametr out by se alespoň naplnil. Důvodem je, že EF dotazy používají odložené provádění.




  1. Vrátí hodnotu a sadu výsledků z uložené procedury classic asp

  2. Vyhledejte „shoda celého slova“ pomocí vzoru LIKE pro SQL Server

  3. Načítání informací o datových typech pro sloupce v Oracle OCCI ResultSet

  4. NodeJS odpověděl Časové pásmo MySQL je jiné, když načítám přímo z MySQL