Czołem
Mam sobie taką procedurę na bazie MS SQL
CREATE PROCEDURE [dbo].[spMultiResultSetTest]
AS
BEGIN
SELECT 'Wynik 1' AS Result1Value
SELECT 'Wynik 2' AS Result2Value
END
Chcę to obsłużyć po stronie aplikacji i zapisać wynik każdego selecta do DataTable i załadować do DataSet.
Niestety, ale to nie śmiga. Pobiera tylko dla pierwszego selecta.
Poniżej przykład konkretnie dla dwóch zestawów wyników.
public class TestDbContext : ITestDbContext
{
public TestDbContext(DbContextOptions<TestDbContext> options)
: base(options)
{
}
//jakieś tam DbSety i inne metody
public async Task<DataSet> ExecuteStoredProcedureWithMultipleResultsAsync(string spName, IEnumerable<SqlParameter> parameters = null)
{
DataSet result = new();
DataTable dtTable = new();
var connection = Database.GetDbConnection();
using (var cmd = connection.CreateCommand())
{
cmd.CommandText = spName;
cmd.CommandType = CommandType.StoredProcedure;
if (cmd.Connection.State != ConnectionState.Open)
cmd.Connection.Open();
if(parameters is not null)
cmd.Parameters.AddRange(parameters.ToArray());
using (var reader = await cmd.ExecuteReaderAsync())
{
dtTable.Load(reader);
result.Tables.Add(dtTable);
dtTable = new DataTable();
await reader.NextResultAsync();
dtTable.Load(reader);
result.Tables.Add(dtTable);
}
}
}
Dalej w serwisie do procedur mielę sobie to w taki sposób...
var dataSet = await _chancellorDbContext.ExecuteStoredProcedureWithMultipleResultstAsync(spName, sqlParams);
foreach(DataTable dataTable in dataSet.Tables)
result.Add(dataTable.DataTableToDynamic());
A tu rozszerzenie do DataTable
public static List<dynamic> DataTableToDynamic(this DataTable dataTable)
{
var dt = dataTable;
var result = new List<dynamic>();
foreach (DataRow row in dt.Rows)
{
dynamic dyn = new ExpandoObject();
result.Add(dyn);
foreach(DataColumn column in dt.Columns)
{
var dic = (IDictionary<string, object>)dyn;
if (dt.Columns.Contains(column.ColumnName))
dic[column.ColumnName] = row[dt.Columns[column.ColumnName]];
else
dic[column.ColumnName] = 0;
}
}
return result;
}
Nie bardzo czaję co jest nie tak. Przykładowo jak zrobię coś takiego to działa i przypisuję do result1 i result2.
public class TestDbContext : ITestDbContext
{
public TestDbContext(DbContextOptions<TestDbContext> options)
: base(options)
{
}
//jakieś tam DbSety i inne metody
public async Task<DataSet> ExecuteStoredProcedureWithMultipleResultsAsync(string spName, IEnumerable<SqlParameter> parameters = null)
{
DataSet result = new();
DataTable dtTable = new();
string result1 = null;
string result2 = null;
var connection = Database.GetDbConnection();
using (var cmd = connection.CreateCommand())
{
cmd.CommandText = spName;
cmd.CommandType = CommandType.StoredProcedure;
if (cmd.Connection.State != ConnectionState.Open)
cmd.Connection.Open();
if(parameters is not null)
cmd.Parameters.AddRange(parameters.ToArray());
using (var reader = await cmd.ExecuteReaderAsync())
{
result1 = reader.GetString("Result1Value");
await reader.NextResultAsync();
result1 = reader.GetString("Result2Value");
}
}
}
Prośba o wskazanie jak to zrobić tak aby działało.