在许多示例中我看到IDataReader
而不是DbDataReader
的用法(并使用其他ADO.NET接口而不是相应的类)。
我知道IDataReader
是一个接口而DbDataReader
是一个类,依此类推......我的问题不是接口与类的不同之处。
IDataReader
描述了通用数据读取器的接口。
DbDataReader
也是通用的(但是是抽象类)。
他们的使用示例似乎是等效的。
为什么要使用通用数据读取器接口而不是使用通用数据读取器类?哪些情况只需要使用界面?哪些情况只需要使用课程?
一个典型的例子:
DbCommand cmd = conn.CreateCommand();
.....................
using (IDataReader reader = cmd.ExecuteReader())
{
grid.DataSource = reader;
grid.DataBind();
}
答案 0 :(得分:6)
DbDataReader
也是通用的
嗯,它是抽象,但不是泛型。可能是一个语义参数,但它是不同读者的基类(SqlDataReader
,OleDbDataReader
等。)
在抽象基类上使用接口的主要好处是,如果有人决定使用不继承自DbDataReader
的数据阅读器。
哪些案例只需要使用类
总是创建具体类 - 接口只是用来表示“我不关心具体类是什么,只要它遵循与这些方法/属性的契约”。
答案 1 :(得分:2)
答案是实现依赖关系的抽象。通常我们尝试使用泛型接口,以便使用该接口的类独立于实际实现。
考虑一下你的类是否正在使用IDataReader,有一天你需要提出IDataReader的另一个实现,它可以从文件中读取数据,就这样说,然后你需要做的就是创建另一个IDataReader实现并初始化你的实例变量。
另外还有其他一些好的做法,例如Dependency Injection,Unit Testing,当你编写抽象和面向接口的代码时,这些做法是可以实现的
花一些时间进行良好的编码实践,例如阅读此book
答案 2 :(得分:0)
DbDataReader是与接口相对的抽象类。
您可以使用DbDataReader使用自己的派生读取器来拦截值获取器,当您需要从SqlDataReader实例中拦截说说Getters时很有用
public class MyReader : DbDataReader
{
SqlDataReader _reader;
public Reader(DbDataReader reader)
{
_reader = (SqlDataReader)reader;
}
public override string GetString(int ordinal)
{
return _reader.GetString(ordinal).Trim();
}
...
using(var reader = new MyReader(command.ExecuteReader()))
{
... 但是,没有DbCommandInterceptor时,此示例的用处不如您将以更横切的方式使用它。说您需要在DbContext中使用Trim()ALL字符串