C# SqlDataReader抛出;当不存在数据时读取的尝试无效”;但面包机并没有
我使用Microsoft SQL Server迁移助手将Access数据库迁移到SQL 现在,我无法读取数据C# SqlDataReader抛出;当不存在数据时读取的尝试无效”;但面包机并没有,c#,sql,ms-access,oledb,C#,Sql,Ms Access,Oledb,我使用Microsoft SQL Server迁移助手将Access数据库迁移到SQL 现在,我无法读取数据 returnreader.GetInt32(0)在检索到32行之后,当不存在数据时,抛出无效的读取尝试异常。如果我将CommandBehavior.SequentialAccess添加到我的命令中,我每次都可以读取265行 数据 查询(在SQL Management Studio中): 第32行没有什么特别之处,如果我颠倒顺序,仍然是第32行杀死了它 第265排,只是为了更好的测量
returnreader.GetInt32(0)代码>在检索到32行之后,当不存在数据时,抛出无效的读取尝试
异常。如果我将CommandBehavior.SequentialAccess
添加到我的命令中,我每次都可以读取265行
数据
查询(在SQL Management Studio中):
第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);
});
}
}
wait reader.ReadAsync()
返回true,但当GetProduct(reader)
调用reader.GetInt32(0)时代码>第32次抛出异常
如果数据小于32行,或者在顺序访问
的情况下小于265行,则可以正常工作。
我尝试增加命令超时
,但没有效果。当我再次切换到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>()
};
}
好了,时间越来越长了。:)
多亏了@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;
}
}
private静态异步任务运行()
{
var result=新列表();
字符串结构=@“…”;
var con=新的SqlConnection(构造);
con.Open();
使用(var命令=新的SqlCommand(“从Products2中选择*,其中Products2.PgId=@p;”,con))
{
Add(新的SqlParameter(“p”,337));
等待任务。运行(异步()=>
{
使用(var productReader=await command.ExecuteReaderAsync())
while(等待productReader.ReadAsync())
{
结果。添加(新产品)
{
Id=productReader.GetInt32(0),
Number=productReader.GetString(2),
EanNo=productReader.GetString(3),
频率=productReader.GetInt16(4),
状态=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);
}
});
}
控制台。写入线(“结束”);
}
私有静态IEnumerable GetColumnValues(SqlDataReader productReader)
{
var columnValues=新列表();
int-columnIndex=11;
而(!productReader.IsDBNull(columnIndex))
Add(productReader.GetInt32(columnIndex++);
返回列值;
}
}
以下是Access中的数据,以防万一:
我设法解决了这个问题
但我仍然有疑问,因为我不明白为什么这不会影响访问
我改变了:
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);
});
}
}
公共异步任务ExecuteAsync(字符串查询、操作OneExecute、参数DataParameter[]参数)
{
使用(var命令=builder.BuildCommand(查询))
{
foreach(参数中的var参数)
command.AddParameter(参数);
如果(!connection.IsOpen)
connection.Open();
等待任务。运行(异步()=>
{
使用(var reader=await command.ExecuteAsync())
if(等待reader.ReadAsync())
onExecute(阅读器);
});
}
}
致:
public async Task ExecuteAsync(字符串查询、Func onExecute、params DataParameter[]参数)
{
使用(var命令=builder.BuildCommand(查询))
{
foreach(参数中的var参数)
command.AddParameter(参数);
如果(!connection.IsOpen)
connection.Open();
使用(var reader=await command.ExecuteAsync())
等待一个执行者(读者);
}
}
如果有人能解释这有什么帮助,我会非常感激。我设法解决了这个问题
但我仍然有疑问,因为我不明白为什么这不会影响访问
我改变了:
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);
});
}
}
公共异步任务ExecuteAsync(字符串查询、操作OneExecute、参数DataParameter[]参数)
{
使用(var命令=builder.BuildCommand(查询))
{
foreach(参数中的var参数)
command.AddParameter(参数);
如果(!connection.IsOpen)
connection.Open();
等待任务。运行(异步()=>
{
使用(var reader=await command.ExecuteAsync())
if(等待reader.ReadAsync())
onExecute(阅读器);
});
}
}
致:
public async Task ExecuteAsync(字符串查询、Func onExecute、params DataParameter[]参数)
{
使用(var命令=builder.BuildCommand(查询))
{
foreach(参数中的var参数)
command.AddParameter(参数);
如果(!connection.IsOpen)
connection.Open();
使用(var reader=await command.ExecuteAsync())
等待一个执行者(读者);
}
}
如果有人能解释这有什么帮助,我会非常感激。不要异步执行,您的问题可能会消失。@BensaysNo
public long ReadLong(int columnIndex)
{
return reader.GetInt32(columnIndex);
}
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;
}
}
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);
});
}
}
public async Task ExecuteAsync(string query, Func<IDataReader, Task> onExecute, params DataParameter[] parameters)
{
using(var command = builder.BuildCommand(query))
{
foreach(var parameter in parameters)
command.AddParameter(parameter);
if(!connection.IsOpen)
connection.Open();
using(var reader = await command.ExecuteAsync())
await onExecute(reader);
}
}