SQL Server How to get the list of data returned from stored procedure while using ExecuteSqlInterpolatedAsync in Entity Framework Core

utugiqy6  于 2023-10-15  发布在  其他
关注(0)|答案(1)|浏览(96)

I am using ExecuteSqlInterpolatedAsync in my .NET 6 Entity Framework Core project, and I am expecting to get a list of items as result, but it's just returning -1.

This is my code:

public async Task<int> Report(string sStartDate, string sEndDate, string spName)
{
    try
    {
        #region Fetch From DB
        var paramToDt = new SqlParameter("@TODATE", SqlDbType.VarChar);
        paramToDt.Value = sStartDate;

        var paramFrmDt = new SqlParameter("@FROMDATE", SqlDbType.VarChar);
        paramFrmDt.Value = sEndDate;

        var data = await Task.Run(() => _dbContext.Database.ExecuteSqlInterpolatedAsync($"EXEC {spName} @TODATE={paramToDt},@FROMDATE={paramFrmDt}"));      
        #endregion

        return 0;
    }
    catch (Exception ex)
    {
        throw ex;
    }    
}

While debugging and seeing the value in the data object it showed as -1, but I expected a list because in the stored procedure, there is a select statement.

kiz8lqtg

kiz8lqtg1#

From the ExecuteSqlInterpolated method,
Executes the given SQL against the database and returns the number of rows affected.

Instead, you should use either FromSqlInterpolated or FromSqlRaw method in order to fetch the queried records from the SQL.

Note that this requires creating a DbSet with a keyless entity type. Unless you are using EF Core 7.0 which supports Querying scalar (non-entity) types via _context.Database.Query<T>() . Reference: Raw SQL Query without DbSet - Entity Framework Core

public DbSet<EntityModel> EntityModels { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<EntityModel>().HasNoKey();
}

And you need to modify the return type of the Report method as List<EntityModel> with EntityModel is your model class for the queried record.

public async Task<List<EntityModel>> Report(string sStartDate, string sEndDate, string spName)
{
    try
    {
        #region Fetch From DB
        var paramToDt = new SqlParameter("@TODATE", SqlDbType.VarChar);
        paramToDt.Value = sStartDate;

        var paramFrmDt = new SqlParameter("@FROMDATE", SqlDbType.VarChar);
        paramFrmDt.Value = sEndDate;

        var data = await _dbContext.EntityModels
            .FromSqlInterpolated($"EXEC {spName} @TODATE={paramToDt},@FROMDATE={paramFrmDt}")
            .ToListAsync();      

        #endregion
        return data;
    }
    catch (Exception ex)
    {
        throw ex;
    }    
}

Note that throw ex; will not preserve the original stack trace information of the exception. You should be concerned regarding it, or else you should use throw; or remove the try-catch block as there is no further action to be handled when the exception is hit.

Reference: Querying scalar (non-entity) types

相关问题