Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The output parameter got a value 'null' of Stored Procedure. #10925

Closed
faust21 opened this issue Feb 9, 2018 · 8 comments
Closed

The output parameter got a value 'null' of Stored Procedure. #10925

faust21 opened this issue Feb 9, 2018 · 8 comments
Labels
closed-no-further-action The issue is closed and no further action is planned.

Comments

@faust21
Copy link

faust21 commented Feb 9, 2018

I have a own-defined DbSet<> class, after i call the FromSql method, i got a value null.

public IQueryable<SPCreateDirectOrder> CreateDirectOrder(string userName, string goodsJson, out int errorCode)
        {
            SqlParameter[] prms = new SqlParameter[]
            {
                new SqlParameter{ParameterName = "UserName", DbType = DbType.StringFixedLength, Size=50, Value = userName},
                new SqlParameter{ParameterName = "GoodsJson", DbType = DbType.String, Value = goodsJson},
                new SqlParameter{ParameterName = "ErrorCode", DbType = DbType.Int32, Direction = ParameterDirection.Output}
            };

            var qryResult = SPCreateDirectOrder.FromSql("EXECUTE dbo.procCreateDirectOrder @UserName,@GoodsJson,@ErrorCode OUTPUT", prms);

            errorCode = Convert.ToInt32(prms[2].Value);

            return qryResult;
        }

I can ensure the procCreateDirectOrder runs well, but the prms[2].Value is null.

@smitpatel
Copy link
Member

Duplicate of #9277

Which version of EF Core are you using? This has been fixed in 2.0.1 version.

@faust21
Copy link
Author

faust21 commented Feb 9, 2018

@smitpatel But i'm using the 2.0.1 version.

@smitpatel
Copy link
Member

Is value of errorCore is null or prms[2].Value is null?

@faust21
Copy link
Author

faust21 commented Feb 9, 2018

@smitpatel The prms[2].Value is null.

@smitpatel
Copy link
Member

@Whatsaf - Please share a repro code which can demonstrate the issue.

In above code snippet,
qryResult is IQueryable so query is constructed and not executed. Untill the query is executed (perhaps by calling ToList on it), the out parameter value will not be populated.
prms is local variable in the function, so outside of the function it cannot be accessed especially after actually executing the query returned.
errorCode is field/property in the class enclosing this method but it takes value of prms[2].Value before query is executed which will be null at that time. So checking value of errorCode will give null only even though later the value is populated.

@faust21
Copy link
Author

faust21 commented Feb 9, 2018

@smitpatel

  1. Create a procedure like this:
CREATE PROCEDURE procOutputValue
  @ReturnCode int OUTPUT
  AS

  set @ReturnCode=1
  SELECT 'succed' as Message
GO
  1. Scaffold the DbContext and create a class to hold the procedure's return value.
public class ProcResult
    {
        public string Message { get; set; }
    }
  1. In the DbContext class, create a property:
    private DbSet<ProcResult> ProcResult { get; set; }
    and in the OnModelCreating method place the below codes:
modelBuilder.Entity<ProcResult>(entity =>
            {
                entity.HasKey(e => e.Message);
            });

Finally, call the FromSql method like this:

public List<ProcResult> ExecProc(out int returnCode)
        {
            var parameters = new[] {
                new SqlParameter{ ParameterName = "ReturnCode", DbType = DbType.Int32, Direction = ParameterDirection.Output }
            };

            var result = ProcResult.FromSql("EXECUTE procOutputValue @ReturnCode OUTPUT", parameters);

            returnCode = Convert.ToInt32(parameters[0].Value);

            return result.ToList();
        }

and the returnCode will be 0, not 1 expected.

@ajcvickers
Copy link
Member

@Whatsaf As @smitpatel said above, the output parameter will not be set until after the query has been enumerated. In other words, you'll need to run result.ToList() before getting the value:

var queryResults = result.ToList();

returnCode = Convert.ToInt32(parameters[0].Value);

return queryResults;

This is the behavior of the SQL Server provider for .NET (SqlClient) and is not something that EF can change.

@ajcvickers ajcvickers added closed-no-further-action The issue is closed and no further action is planned. and removed closed-duplicate labels Feb 9, 2018
@faust21
Copy link
Author

faust21 commented Feb 11, 2018

@ajcvickers I'm so sorry about that, i just couldn't understood what smitpatel said. But now with the codes, i can understand that clearly. Now, the codes runs well. Apologize for my foolish.

@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-no-further-action The issue is closed and no further action is planned.
Projects
None yet
Development

No branches or pull requests

3 participants