我想从数据库中读取数据到列表中。
我尝试了以下代码
public List<T> StoredProcedureForIList<T>(string spName, params IDataParameter[] commandParameters)
{
List<T> list = new List<T>();
T item;
Type listItemType = typeof(T);
item = (T)Activator.CreateInstance(listItemType);
list.Add(item);
using (IDatabaseConnection connection = new DatabaseConnection())
{
IDbCommand cmd = connection.CreateCommandForStoredProcedure(spName);
foreach (SqlParameter par in commandParameters)
{
cmd.Parameters.Add(par);
}
try
{
using (IDataReader reader = cmd.ExecuteReader())
{
while (reader != null && reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
var prop = listItemType.GetProperty(reader.GetName(i));
prop.SetValue(item, reader[i], null);
}
list.Add(item);
}
}
}
catch(Exception ex)
{ }
return list;
}
}
但问题是,当for循环开始时,读者会丢失数据。
数据读取器ResultView值为Enumeration,没有结果。
答案 0 :(得分:5)
我的猜测是在执行循环期间发生了一些错误。这种技术......
try
{
...
}
catch(Exception ex)
{ }
...确保忽略此错误,所得到的结果都是不完整的。正如您所注意到的,这使得调试非常困难。所以不要这样做。
因此,解决方案是:
try { ... } catch(Exception ex) {}
替换...
),而且,永远不要再写catch (Exception ex) {}
了。 ;-)执行正确的错误处理,或者根本不进行错误处理。
答案 1 :(得分:2)
读者不会丢弃行;读者经过了充分的考验。吞咽异常无济于事。如果我不得不猜测,这里的问题是你一遍又一遍地添加相同的item
。实际上,你将它添加N + 1次(即使没有返回任何行,你也可以在顶部添加一次)。
但是,我可以建议:只使用类似dapper的内容,它可以执行上述所有操作,但是:它使它正确,并且b:它经过高度优化(它会发出自定义IL以避免持续反射,以及缓存IL)。它将类似于:
var list = connection.Query<T>(procName, namedArgs,
commandType: CommandType.StoredProcedure).ToList();
namedArgs
将传入@id
和@name
,例如:
new {id=123, name="abc"}
即
int id = ...
string name = ...
var list = connection.Query<T>("MyProc", new {id, name},
commandType: CommandType.StoredProcedure).ToList();