Reputation: 232
I must load a large set of data from SQL Server with ado.net.
This data returned from a slow stored procedure. I can't store result in temporary table because I don't know structure of result table. So I cannot do something like:
CREATE TABLE #temp
(
ID INT,
NAME VARCHAR(100),
...
)
INSERT INTO #temp Exec dbo.proc @param=1
SELECT COUNT(*) FROM #temp
SELECT * FROM #temp
So as the data set is large, I use a SqlDataReader
. But for progress I should know count of row for this data.
private SqlCommand _asyncCmd;
private SqlDataReader _reader;
private SqlConnection _con;
private IAsyncResult _asyncResult;
public void GetDictionaryMetadataAsync(int param)
{
_con = new SqlConnection(_connectionString);
_asyncCmd = new SqlCommand("SP_procedure", _con);
_asyncCmd.CommandType = CommandType.StoredProcedure;
_asyncCmd.CommandTimeout = 0;
_asyncCmd.Parameters.Add(new SqlParameter("@param", SqlDbType.Int));
_asyncCmd.Parameters["@param"].Value = param;
_asyncCmd.Connection.Open();
var callback = new AsyncCallback(EndExecuteReader);
_asyncResult = _asyncCmd.BeginExecuteReader(callback, _asyncCmd);
}
private void EndExecuteReader(IAsyncResult result)
{
_reader = _asyncCmd.EndExecuteReader(result);
var command = new SqlCommand("SELECT @@ROWCOUNT", _con);
// GETTING COUNT
var count = command.ExecuteScalar() as int?;
if (!count.HasValue) throw new NullReferenceException();
Count = count.Value;
}
public IEnumerable<object[]> GetDictionaryMetadataAsyncEnd()
{
_asyncResult.AsyncWaitHandle.WaitOne();
if (!_reader.Read())
yield break;
var values = new object[_reader.FieldCount];
_reader.GetValues(values);
yield return values;
while (_reader.Read())
{
_reader.GetValues(values);
yield return values;
}
}
But this part of code
// GETTING COUNT
var count = command.ExecuteScalar() as int?;
return always 0.
Do you have any idea how can I do it?
Thanks in advance.
Upvotes: 1
Views: 1450
Reputation: 909
The most probable reason reason you get @@ROWCOUNT = 0, is running command in a separate implicitely defined db transaction (check the @@SPID value to make sure).
The solution is using a single explicitly defined transaction within your c# code.
Notice, that "SET NOCOUNT ON" option within the stored procedure causes no effects to @@ROWCOUNT value:
The @@ROWCOUNT function is updated even when SET NOCOUNT is ON.
PS. "MultipleActiveResultSets=True" option for SqlConnection connection string helped
Upvotes: 2