我使用Microsoft SQL Server遷移助理將Access數據庫遷移到SQL。SqlDataReader拋出「當無數據存在時無效嘗試讀取」但OleDbReader不會
現在,我無法讀取數據。
return reader.GetInt32(0);
拋出Invalid attempt to read when no data is present
異常後行檢索。如果我將CommandBehavior.SequentialAccess
添加到我的命令中,則可以每次讀取行,。
數據
查詢(在SQL Management Studio中):
SELECT *
FROM Products2
WHERE Products2.PgId = 337;
沒有什麼特別之處排32,如果我顛倒順序,但仍排32,殺死它。
行265,只是爲了好措施。
代碼
查詢:
SELECT *
FROM Products2
WHERE Products2.PgId = @productGroupId;
參數:
Name = "productGroupId"
Value = 337
執行:
public async Task ExecuteAsync(string query, Action<IDataReader> onExecute, params DataParameter[] parameters)
{
using(var command = builder.BuildCommand(query))
{
foreach(var parameter in parameters)
command.AddParameter(parameter);
if(!connection.IsOpen)
connection.Open();
await Task.Run(async() =>
{
using(var reader = await command.ExecuteAsync())
if(await reader.ReadAsync())
onExecute(reader);
});
}
}
和閱讀:
await executor.ExecuteAsync(query, async reader =>
{
do
{
products.Add(GetProduct(reader));
columnValues.Enqueue(GetColumnValues(reader).ToList());
} while(await reader.ReadAsync());
}, parameters.ToArray());
await reader.ReadAsync()
返回true,但當GetProduct(reader)
呼叫reader.GetInt32(0);
第32屆的時候,它會拋出異常。
它工作正常,如果數據少於32行,或者在SequentialAccess
的情況下爲265。 我試圖增加CommandTimeout
,但它沒有幫助。當我再次將連接交換到OleDb
時,它工作得很好。
在此先感謝。
編輯
如果我只有幾個特定的列查詢替換*
,它的工作原理。當我讀到〜12列時,它失敗了,但晚於第32行。
根據要求,GetProduct:
private Product GetProduct(IDataReader productReader)
{
return new Product
{
Id = productReader.ReadLong(0),
Number = productReader.ReadString(2),
EanNo = productReader.ReadString(3),
Frequency = productReader.ReadInt(4),
Status = productReader.ReadInt(5),
NameId = productReader.ReadLong(6),
KMPI = productReader.ReadByte(7),
OEM = productReader.ReadString(8),
CurvesetId = productReader.ReadInt(9),
HasServiceInfo = Convert.ToBoolean(productReader.ReadByte(10)),
ColumnData = new List<ColumnData>()
};
}
GetColumnData:
private IEnumerable<long> GetColumnValues(IDataReader productReader)
{
var columnValues = new List<long>();
int columnIndex = 11;
while(!productReader.IsNull(columnIndex))
columnValues.Add(productReader.ReadLong(columnIndex++));
return columnValues;
}
和適配器:
public long ReadLong(int columnIndex)
{
return reader.GetInt32(columnIndex);
}
正常的,這也越來越長。 :) 感謝@Igor,我試着創建一個小的工作示例。這似乎很好地工作:
private static async Task Run()
{
var result = new List<Product>();
string conString = @" ... ";
var con = new SqlConnection(conString);
con.Open();
using(var command = new SqlCommand("SELECT * FROM Products2 WHERE Products2.PgId = @p;", con))
{
command.Parameters.Add(new SqlParameter("p", 337));
await Task.Run(async() =>
{
using(var productReader = await command.ExecuteReaderAsync())
while(await productReader.ReadAsync())
{
result.Add(new Product
{
Id = productReader.GetInt32(0),
Number = productReader.GetString(2),
EanNo = productReader.GetString(3),
Frequency = productReader.GetInt16(4),
Status = productReader.GetInt16(5),
NameId = productReader.GetInt32(6),
KMPI = productReader.GetByte(7),
OEM = productReader.GetString(8),
CurvesetId = productReader.GetInt16(9),
HasServiceInfo = Convert.ToBoolean(productReader.GetByte(10))
});
GetColumnValues(productReader);
}
});
}
Console.WriteLine("End");
}
private static IEnumerable<long> GetColumnValues(SqlDataReader productReader)
{
var columnValues = new List<long>();
int columnIndex = 11;
while(!productReader.IsDBNull(columnIndex))
columnValues.Add(productReader.GetInt32(columnIndex++));
return columnValues;
}
}
下面是訪問數據,以防萬一:
不要這樣做異步,你的問題可能會消失。 – Ben
@BensaysNotoPoliticsonSO,你如何建議我保持敏感呢? –
通過正確索引它使查詢很快。 – Ben