我使用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