我们有一个n层Web应用程序,可以从SQL Server中提取数据.我们的数据访问逻辑返回一个SqlDataReader,其数据随后用于创建我们的Business对象(也称为数据传输对象).
我们希望构建单元测试以检查我们的代码,这些代码解释这些SqlDataReader对象返回的数据以构建我们的Business对象.
因此,在单元测试期间,似乎需要构建存根来替换SqlDataReader对象.可能相当典型,我们的SqlDataReader对象通常返回多个记录集,每个记录集都有多行.
提前谢谢了
格里夫
使用SqlDataReader的方法,我可以通过传入它的序数来获取列的值,例如,如果我传入read.GetValue(0),则为第一列的值,如果我传入,则为第二列read.GetValue(1).
在查看这些方法时,我没有看到通过传入列名称(例如ColumnID)来获取列值的选项.在我的神话示例中,我想传入read.GetValueofColumn("ColumnID")并读取列中的值(请注意,GetValueofColumn从方法列表中可以看出,该方法不存在).
我错过了这样做的方法,还是一种方法呢?
我注意到从IDataReader使用声明中读取一些我无法理解的好奇心.虽然我确信答案很简单.
为什么在内部using (SqlDataReader rd) { ... }如果我直接执行一个yield return阅读器在阅读期间保持打开状态.但是,如果我执行直接return调用SqlDataReader扩展方法(如下所述),读者在枚举可以实现之前关闭?
public static IEnumerable<T> Enumerate<T>(this SqlDataReader rd)
{
while (rd.Read())
yield return rd.ConvertTo<T>(); //extension method wrapping FastMember
rd.NextResult();
}
Run Code Online (Sandbox Code Playgroud)
为了完全清楚我在问什么,我不确定为什么以下内容根本不同:
一个充实的例子,根据@ TimSchmelter的要求:
/*
* contrived methods
*/
public IEnumerable<T> ReadSomeProc<T>() {
using (var db = new SqlConnection("connection string"))
{
var cmd = new SqlCommand("dbo.someProc", db);
using(var rd = cmd.ExecuteReader())
{
while(rd.Read())
yield return rd.ConvertTo<T>(); //extension method wrapping FastMember
}
}
}
//vs
public IEnumerable<T> ReadSomeProcExt<T>() …Run Code Online (Sandbox Code Playgroud) 我想从数据库中检索十进制值,我想知道检查空值的推荐方法.
我在MSDN上看到过- DBNull.Value字段很少使用此检查.
因此,reader.IsDBNull检查空值是最好/最有效的方法吗?
我创建了2个示例方法:
public static decimal? GetNullableDecimal(SqlDataReader reader, string fieldName)
{
if (reader[fieldName] == DBNull.Value)
{
return null;
}
return (decimal)reader[fieldName];
}
public static decimal? GetNullableDecimal_2(SqlDataReader reader, string fieldName)
{
if (reader.IsDBNull(reader[fieldName]))
{
return null;
}
return (decimal)reader[fieldName];
}
Run Code Online (Sandbox Code Playgroud)
大多数情况下,字段将为空.
提前致谢!
如何SqlDataReader在另一个内部实现SqlDataReader?
我的问题是我有一个SqlDataReader.我发布while (reader.read())并在while循环中我必须创建另一个SqlDataReader从数据库中读取.但我得到关于连接已经打开的例外情况.
那么解决问题的最佳方法是什么?
编辑:
我正在使用clr来创建我的存储过程.我试图MultipleActiveResultSets=true;在clr和项目的连接字符串中放置,并且当我在SQL Server上测试我的存储过程时发生异常:
System.InvalidOperationException:已经有一个与此命令关联的打开DataReader,必须先关闭它.
我知道我之前提过了一个相关的问题.我只是想到了另一个想法.
using (SqlConnection conn = new SqlConnection('blah blah'))
{
using(SqlCommand cmd = new SqlCommand(sqlStatement, conn))
{
conn.open();
// *** do I need to put this in using as well? ***
SqlDataReader dr = cmd.ExecuteReader()
{
While(dr.Read())
{
//read here
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
参数是:由于SqlDataReader dr对象不是一个新的对象,如连接或命令对象,它只是一个指向cmd.ExecuteReader()方法的引用,我是否需要将阅读器放在一个using.(现在基于我以前的帖子,我的理解是任何使用的对象IDisposable需要放入using,并SQLDataReader继承IDisposable,所以我需要把它.我的判断是否正确?)我只是困惑,因为它不是一个新的对象,它会在处理一个只是命令的引用指针的对象时引起任何问题吗?
非常感谢
如何添加SqlDataReader返回通用List的值?我有一个方法,我SqlDataReader用来CategoryID从Category表中获取.我想添加所有CategoryID通用列表.
这个剂量不起作用,因为它只返回一个categoryID,这是最后一个.我想将所有内容添加categoryID到列表中,然后返回它们.
我怎么做?
SqlConnection connection = null;
SqlDataReader reader = null;
SqlCommand cmd = null;
try
{
connection = new SqlConnection(connectionString);
cmd = new SqlCommand("select CategoryID from Categories", connection );
connection.Open();
List<int> catID = new List<int>();
dr = cmd.ExecuteReader();
while (dr.Read())
{
catID.Add(Convert.ToInt32(dr["CategoryID"].ToString()));
}
}
finally
{
if (connection != null)
connection.Close();
}
return catID;
Run Code Online (Sandbox Code Playgroud) 为什么在将0转换为整数时SqlDataReader会抛出异常?
?dataReader(3)
0 {Short}
Short: 0
?dataReader.GetInt16(3)
0
?dataReader.GetInt32(3)
{"Specified cast is not valid."}
_HResult: -2147467262
_message: "Specified cast is not valid."
Data: {System.Collections.ListDictionaryInternal}
HelpLink: Nothing
HResult: -2147467262
InnerException: Nothing
IsTransient: False
Message: "Specified cast is not valid."
Source: "System.Data"
StackTrace: " at System.Data.SqlClient.SqlBuffer.get_Int32()
at System.Data.SqlClient.SqlDataReader.GetInt32(Int32 i)"
TargetSite: {Int32 get_Int32()}
Run Code Online (Sandbox Code Playgroud) 如果我想在不同的表上运行多个SELECT查询,我可以为所有这些表使用相同的SqlDataReader和SqlConnection吗?以下是明智的吗?(我输入的速度很快,所以缺少try/catch):
MySqlCommand myCommand = new MySqlCommand("SELECT * FROM table1", myConnection);
myConnection.Open();
SqlDataReader myDataReader = myCommand.ExecuteReader();
while(myReader.Read())
{
//Perform work.
}
myCommand.commandText = "SELECT * FROM table2";
myReader = myCommand.ExecuteReader();
while(myReader.Read())
{
//Perform more work
}
myReader.Close();
myConnection.Close();
Run Code Online (Sandbox Code Playgroud)
非常感谢.
sqldatareader ×10
c# ×8
.net ×2
ado.net ×2
sql ×2
datareader ×1
dbnull ×1
dispose ×1
ienumerable ×1
nunit ×1
sql-server ×1
stub ×1
unit-testing ×1
yield-return ×1