5

Tôi có một thủ tục Oracle lưu trữ đơn giản mà được ba thông số thông qua tại, và có một tham số đầu ra:Gọi thủ tục lưu sẵn Oracle bằng Entity Framework với tham số đầu ra?

CREATE OR REPLACE PROCEDURE RA.RA_REGISTERASSET 
(
    INPROJECTNAME IN VARCHAR2 
    ,INCOUNTRYCODE IN VARCHAR2 
    ,INLOCATION IN VARCHAR2 
    ,OUTASSETREGISTERED OUT VARCHAR2 
) 
AS 
BEGIN 
    SELECT 
     INPROJECTNAME || ', ' || INLOCATION || ', ' || INCOUNTRYCODE 
    INTO 
     OUTASSETREGISTERED 
    FROM 
     DUAL;  
END RA_REGISTERASSET; 

Tôi cố gắng để sử dụng Entity Framework 6.1 để lấy lại giá trị OutAssetRegistered, tuy nhiên, tôi nhận được một null sau khi gọi SqlQuery mà không có ngoại lệ:

public class CmdRegisterAssetDto 
{ 
     public string inProjectName { get; set; } 
     public string inCountryCode { get; set; } 
     public string inLocation { get; set; } 
     public string OutAssetRegistered { get; set; } 
} 

// ---------------------------------- --------------------------

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 query = ctx.Database.SqlQuery<CmdRegisterAssetDto>(sql, projectNameParam, countryCodeParam, locationParam, assetRegisteredParam 
    ); 

    assetRegistered = (string)assetRegisteredParam.Value; 
} 

Tôi đã chiến đấu để làm việc này không có kết quả, đã kiểm tra các blog khác nhau, tất cả các hoạt động crud khác hoạt động, bất cứ ai có thể vui lòng hỗ trợ và chỉ đạo cho tôi nơi tôi đang đi sai?

+0

Tôi có yêu cầu tương tự là bạn có thể làm cho nó được giải quyết? –

+0

Tôi gặp vấn đề tương tự, vui lòng cho tôi biết nếu bạn tìm thấy giải pháp. – pforsthoff

Trả lời

0

Trong trường hợp này, bạn không nên gọi:

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

Nhưng thay vì được gọi:

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

Chú ý rằng sự khác biệt hiệu quả duy nhất là SqlQuery<CmdRegisterAssetDto> được thay thế bằng ExecuteSqlCommand. Điều này cũng có nghĩa là DTO là không cần thiết. Nếu không, mã của bạn có vẻ như nó sẽ hoạt động. Đây là mã ban đầu của bạn một cách trọn vẹn với những thay đổi tôi đã đề cập:

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

Để chứng minh lý thuyết của tôi, tôi sao chép các hành vi vô mà bạn đang gặp phải và sau đó thực hiện một thay đổi. Nó treo một chút (có lẽ để cho EF đá vào bánh răng), nhưng sau đó thực hiện nhanh chóng mỗi lần sau đó. Trong mỗi trường hợp, tôi tìm thấy một giá trị chờ đợi trong tham số ngoài.

Nếu bất cứ ai ngoài kia đang chạy vào rắc rối, có một biến thể longhand rằng sẽ chăm sóc của các chi tiết kịch bản cho bạn:

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

Là một suy nghĩ, bạn về mặt kỹ thuật có thể đi với giải pháp ban đầu của bạn nếu bạn gọi các truy vấn ngay lập tức sau (tức là query.FirstOrDefault()). Giá trị trả về của truy vấn sẽ luôn là null, nhưng tham số ngoài của bạn sẽ ít nhất được điền. Điều này là do các truy vấn EF sử dụng thực thi hoãn lại.

Các vấn đề liên quan