この場合、電話をかけるべきではありません:
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;
}
私の理論を証明するために、私はあなたが経験しているヌルの振る舞いを再現し、それからその1つの変更を加えました。それは少しの間ハングしましたが(おそらくEFをギアに入れるため)、その後は毎回すばやく実行されました。いずれの場合も、outパラメーターで待機している値を見つけました。
誰かが問題にぶつかった場合、スクリプトの詳細を処理する長いバリエーションがあります:
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()
)、元のソリューションを使用できます。 )。クエリの戻り値は常にnullになりますが、outパラメータは少なくとも入力されます。これは、EFクエリが遅延実行を使用するためです。