Oracle
 sql >> база данни >  >> RDS >> Oracle

Извикване на съхранена процедура на Oracle с помощта на Entity Framework с изходен параметър?

В този случай не трябва да се обаждате на:

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

Но вместо това се обадете:

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

Забележете, че единствената ефективна разлика е, че SqlQuery<CmdRegisterAssetDto> беше заменено с ExecuteSqlCommand . Това също означава, че DTO е ненужен. В противен случай вашият код изглежда, че трябва да работи. Ето вашия оригинален код в неговата цялост с промените, които споменах:

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

За да докажа теорията си, възпроизведох нулевото поведение, което изпитвате, и след това направих тази промяна. Увисна за малко (вероятно, за да позволи на EF да се задейства), но след това се изпълняваше бързо всеки път след това. Във всеки случай намерих чакаща стойност в изходния параметър.

Ако някой се сблъска с проблеми, има дълъг вариант, който се грижи за подробностите за скрипта вместо вас:

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

Като последваща мисъл, технически бихте могли да използвате първоначалното си решение, ако извикате заявката веднага след това (т.е. query.FirstOrDefault() ). Върнатата стойност на заявката винаги ще бъде нула, но вашият изходящ параметър поне ще бъде попълнен. Това е така, защото EF заявките използват отложено изпълнение.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. C#:Обектът не може да бъде прехвърлен от DbNull към други типове

  2. Мързелива оценка на Oracle PL/SQL оператори в SELECT клаузи на SQL заявки

  3. Преобразуване на Unixtime в Datetime SQL (Oracle)

  4. SQL. Как да се направи препратка към съставен първичен ключ Oracle?

  5. Oracle SQL за непрекъснато групиране