三层架构中如何使用DataReader高手请进!!! DataReader比DataSet速度快,因为在填充DataSet时,实际.net会调用DataReader的。所以我的程序有点地方想用DataReader,但是做为三层架构怎样传递DataReader或者DataReader中的数据。小弟想了很久,发觉不太现实。请哪位高手给个提示! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 http://blog.sina.com.cn/s/blog_4c59c08a0100crrv.html public List<UserInfor> GetList(){ List<UserInfor> list = new List<UserInfor>(); SQLHelper helper = new SQLHelper(); string sql = "select * from UserInfor"; SqlParameter[] prams = null; SqlDataReader sdr = helper.ExecuteDataReader(sql, prams); while (sdr.Read()) { UserInformodel = new UserInfor(); model.Username = sdr["Username"].ToString(); model.Usertype =sdr["Usertype"].ToString(); list.Add(model); } sdr.Close(); return list; }UserInfor 是实体类, 用List<T> 传数据 “怎样传递DataReader ” ??? 什么意思 ?? DataReader 能传递吗???ExecuteReader() 方法读取就可以了 。。 如果datareader一直传递到UI,导致连接无法关闭,这样肯定不现实。现实的就是用datareader读取数据然后用List集合保存后返回 datareader 干嘛要传递?? 放在你数据访问层 读取数据 就行了 http://avatar.profile.csdn.net/6/C/B/2_rock870210.jpg <image herf="http://avatar.profile.csdn.net/6/C/B/2_rock870210.jpg"/> 在DLA层调用DBHelper操作datareader,返回实体类Database db = DBHelper.CreateDataBase(); using (IDataReader reader = db.ExecuteReader(cmd)) { if (reader.Read()) { }} 楼主你没搞清楚三层架构的真正含义,WEB成调用BLL 层 BLL 层 对DAL层经行封装 这是简单的三层, 在BLL 层 你只需要返回数据给WEB层就行了,怎么读 都是先把数据取出来!!! 首先谢谢各位!!在这里我解释一下,我主要写Winform程序,用的是Remoting技术,界面层是调用的接口,而接口再调用的中间层。这样读取数据只能是返回DataSet。我参考了一些书,这些书的例子都是在一层实现的,对于我来说没有什么用。如果按照lester19872007说的那样,如果用DataReader读出,再在中间成生成一个数组或者DataSet和直接填充DataSet没有什么区别,甚至这种方式肯定比直接填充DataSet效率更低。 按照你的意思不如直接填充DataSet,这样效率会更高,我现在是要解决效率问题,所以才想到是否用DataReader来替代DataSet 按照你的意思不如直接填充DataSet,这样效率会更高,我现在是要解决效率问题,所以才想到是否用DataReader来替代DataSet 恩 你用DataReader对象读取数据 然后再用泛型集合保存 并返回 个人认为lz这种较方法是不正确的dataset数据集也,就是数据的集合。一般是一片数据——至少一张表吧,不然没有太大意义而datareeader是一个读取数据的对象,他只是取数据的对象,取到了数据还是要填充到数据容器里面的,这样才可以传递呀所以不管数据容器是什么,还是要填充的dataset也一样啊 关键问题不在传递上面,就像ls几位的说的一样,你想怎么传递都可以但是如果不正确使用datareader将会引起连接池的死锁。这一点我不用多解释,从你提问的方式我想你是很清楚dataset和datareader各自的优缺点的。so,把一个留有安全隐患的ojbect从最下层一直传递到最上层,你可以考虑一下他是否是一个合适且负责任的做法 在三层架构中,数据肯定是在DAL中读出,保存起来了,并且断开和数据库的连接,用datareader读数据是还没有和数据库连接的。三层架构本来就是为了减少开发和环节的耦合,增加访问数据的安全性。所以你的思路和三层架构思想本来就是相驳的。 using System;using System.Collections.Generic;using System.Text;using System.Data;using System.Data.SqlClient;using System.Configuration;using System.Data.OleDb;namespace HoteManager.DAL{public class SqlDBHelper{private readonly string connString = ConfigurationManager.ConnectionStrings["HoteManager"].ToString();public SqlConnection SqlConnection;/// <summary>/// 执行SQL语句,读取数据/// </summary>/// <param name="Sql">SQL 语句</param>/// <returns>SqlDataReader对象</returns>public SqlDataReader GetSqlReader(string Sql){SqlConnection = new SqlConnection(connString);SqlCommand Command = new SqlCommand(Sql, SqlConnection);SqlConnection.Open();SqlDataReader Reader = Command.ExecuteReader();return Reader;}/// <summary>/// 执行SQL语句,读取数据/// </summary>/// <param name="Sql">SQL 语句</param>/// <returns>SqlDataReader对象</returns>public SqlDataReader GetSqlReader(string Sql,string typeName){SqlConnection = new SqlConnection(connString);SqlCommand Command = GetCommand(Sql,typeName,SqlConnection);SqlConnection.Open();SqlDataReader Reader = Command.ExecuteReader();return Reader;}/// <summary>/// 执行SQL语句,返回SqlCommand对象/// </summary>/// <param name="Sql">SQL语句</param>///<param name="typeName">参数</param>/// <returns>SqlCommand对象</returns>public SqlCommand GetCommand(string Sql,string typeName,SqlConnection SqlConnection){SqlCommand Command = new SqlCommand(Sql, SqlConnection);//Command.CommandType = CommandType.StoredProcedure;Command.Parameters.Add("TypeName", SqlDbType.NVarChar, 50).Value = typeName;return Command;}}} DataReader 是只读的 而且一次取一条 DataSet 是一次性取表中数据 可能慢一些具体的哪个更合适 要看你的 需求 三层架构本身的设计原则就是高层依赖低层,逐层调用 ,不依赖具体依赖抽象~~ 换另外一个角度来说 ,datareader是持续连接的,按照楼主的意思,在获取数据后传递到高层的过程中,数据库连接是一直持续连接的,如果此时另有操作数据库,那么就会打开一个新的数据库连接,假如,只是假如,每一个操作都是datareader级操作,那楼主你认为你提到的效率跟一个ui界面持续链接N个数据库连接的资源消耗,哪个影响更大?更何况,现代计算机的配置 网上说 SQLHelper 不是不能实例化吗 SQLHelper helper = new SQLHelper();怎么这里??? 赞同将其转化为List对象,然后进行接下来的操作 楼主你是想在页面上用dataReader直接显示数据来提高效率嘛?这样做是不会得到很大的提升的(可以忽略的)。然而副作用却破坏了整个程序结构。为什么可以忽略呢?虽然DataSet先使用了DataReader,但是其中的操作也只是复制了一下内容,这个是非常非常非常快的。无需操心。 同意LS 觉得没必要 如果非要的话 也许可以使用c#流对象来保存 不过这样好像也要保存 还是要复制 要不你程序哪里要用到数据是在那里创建datareader对象 直接用如有说错 请见谅 三层架构只使用DataReader是明智的,但你不应该把它传递到BLL或者UI层,你应该在DAL层使用它然后立刻关闭,所以最好的做法就是在DAL层Fill一个实体类,让实体类作为三层间的数据通道。有关实际的例子请参看:http://blog.csdn.net/bluedoctor/archive/2010/01/24/5251913.aspx 看来只有自己测试一下,用DataReader读出,手动赋值到数组或者DataSet中,然后把该数组或者DataSet传入界面层。与直接填充DataSet比较,哪个速度快。测试结果我会与大家一起分享。 可以在DBHelper 里面 写个方法啊 概念问题:DataReader是数据读取用的 ,读出来的数据需要存放容器,如Dataset,datatable,IList等你要传值,首先要有数据容器. DBhelpaer类 public static SqlDataReader GetReader(string sql) { SqlCommand cmd = new SqlCommand(sql, Conn); return cmd.ExecuteReader(); }DAOpublic IList<Class> GetClasslist() { List<Class> Class = new List<Class>(); StringBuilder strsql = new StringBuilder(); strsql.Append("select top 10 * from gg_sys_class"); SqlDataReader dr=DBhelpaer.GetReader(strsql.ToString()); if (dr.HasRows) { while (dr.Read()) { Class.Add(SetClass(dr)); } } return Class; } public Class SetClass(SqlDataReader reader) { Class sclass = new Class(); sclass.acadyear = reader["acadyear"].ToString(); sclass.artsciencetype = reader["artsciencetype"].ToString(); sclass.classid = reader["classid"].ToString(); //sclass.classintid = reader["classintid"].ToString(); sclass.classname = reader["classname"].ToString(); sclass.classno = reader["classno"].ToString(); sclass.classtype = reader["classtype"].ToString(); sclass.gradeid = reader["gradeid"].ToString(); sclass.schid = reader["schid"].ToString(); sclass.schooling_length =Convert.ToInt32( reader["schooling_length"]); sclass.section = reader["section"].ToString(); //sclass.GradeName = reader["gradename"].ToString(); return sclass; } 如果只是读取可以用DataReader,如果需要传递个人倾向与List<Entity> 既然三层架构,当然不是传递reader了,三层架构你传递的应该是对象,而不是reader另外 手工和自动填dataset速度几乎没区别 如果你读取的数据只有一条datareader是比DataAdapter(不是dataset)快如果你读取出来的是一个结果集,还是用DataAdapter快,不浪费数据库连接。datareader在读取数据的过程中始终保持一个连接,直到你把它释放。DataAdapter可以一次性读取数据到dataset释放连接,所以不浪费数据库连接。如果你从数据库中得到的是一个值,如int或string你可以用cmd.ExecuteScalar返回object,这是最快的 如果你用datareader来填充DataSet,那相当于用了杀鸡的刀来宰牛 支持ls,而且datareader需要保持数据库连接,而DataAdapter只需要一次连接就ok 要提高效率可以考虑压缩Dataset再传输,我再webservice中用过,效率提升很明显。remoting没测过,你可以试试看 其实我一直怀疑.Net用DataAdapter填充DataSet是不自己也调用DataReader,然后赋值到DataSet中,关闭连接,所以我自己手动用DataReader循环赋值给DataSet,就相当与重新写DataAdapter的Fill()函数。不知这个效率是否比.Net的DataAdapter的Fill()函数效率高。数据量在10万条以上 设置返回类型为DataReader应该就可以了 结贴了!!还是直填充DataSet吧 public List<UserInfor> GetList(){ List<UserInfor> list = new List<UserInfor>(); SQLHelper helper = new SQLHelper(); string sql = "select * from UserInfor"; SqlParameter[] prams = null; SqlDataReader sdr = helper.ExecuteDataReader(sql, prams); while (sdr.Read()) { UserInformodel = new UserInfor(); model.Username = sdr["Username"].ToString(); model.Usertype =sdr["Usertype"].ToString(); list.Add(model); } sdr.Close(); return list; }UserInfor 是实体类, 用List<T> 传数据参考答案来源于:topic.csdn.net我正在使用《Csdn收音机》第一时间获取最新动态! 来个面试题,难道真的是我表达不清楚么?为什么回答都这么怪呢? 怎么用结构数组! webBrowser给下拉列表赋值问题 图片和视频转换成数据流进行加密 gridview其中"序号"列升序排列 用谁用过teechart控件,用C#做..高分高酬劳求帮忙.. 请各高手指教 ACCESS列数限制的问题,急 操作符重载的问题 Help!救命啊!!! 如何把RTF格式内容转换成HTML 如何强制发送QQ群邮件
{
List<UserInfor> list = new List<UserInfor>();
SQLHelper helper = new SQLHelper();
string sql = "select * from UserInfor";
SqlParameter[] prams = null;
SqlDataReader sdr = helper.ExecuteDataReader(sql, prams);
while (sdr.Read())
{
UserInformodel = new UserInfor();
model.Username = sdr["Username"].ToString();
model.Usertype =sdr["Usertype"].ToString();
list.Add(model);
}
sdr.Close();
return list;
}UserInfor 是实体类, 用List<T> 传数据
Database db = DBHelper.CreateDataBase();
using (IDataReader reader = db.ExecuteReader(cmd))
{
if (reader.Read())
{ }
}
在这里我解释一下,我主要写Winform程序,用的是Remoting技术,界面层是调用的接口,而接口再调用的中间层。这样读取数据只能是返回DataSet。我参考了一些书,这些书的例子都是在一层实现的,对于我来说没有什么用。
如果按照lester19872007说的那样,如果用DataReader读出,再在中间成生成一个数组或者DataSet和直接填充DataSet没有什么区别,甚至这种方式肯定比直接填充DataSet效率更低。
dataset数据集也,就是数据的集合。一般是一片数据——至少一张表吧,不然没有太大意义而datareeader是一个读取数据的对象,他只是取数据的对象,取到了数据还是要填充到数据容器里面的,这样才可以传递呀所以不管数据容器是什么,还是要填充的
dataset也一样啊
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Data.OleDb;namespace HoteManager.DAL
{
public class SqlDBHelper
{
private readonly string connString = ConfigurationManager.ConnectionStrings["HoteManager"].ToString();
public SqlConnection SqlConnection;/// <summary>
/// 执行SQL语句,读取数据
/// </summary>
/// <param name="Sql">SQL 语句</param>
/// <returns>SqlDataReader对象</returns>
public SqlDataReader GetSqlReader(string Sql)
{
SqlConnection = new SqlConnection(connString);
SqlCommand Command = new SqlCommand(Sql, SqlConnection);
SqlConnection.Open();
SqlDataReader Reader = Command.ExecuteReader();
return Reader;
}/// <summary>
/// 执行SQL语句,读取数据
/// </summary>
/// <param name="Sql">SQL 语句</param>
/// <returns>SqlDataReader对象</returns>
public SqlDataReader GetSqlReader(string Sql,string typeName)
{
SqlConnection = new SqlConnection(connString);
SqlCommand Command = GetCommand(Sql,typeName,SqlConnection);
SqlConnection.Open();
SqlDataReader Reader = Command.ExecuteReader();
return Reader;
}
/// <summary>
/// 执行SQL语句,返回SqlCommand对象
/// </summary>
/// <param name="Sql">SQL语句</param>
///<param name="typeName">参数</param>
/// <returns>SqlCommand对象</returns>
public SqlCommand GetCommand(string Sql,string typeName,SqlConnection SqlConnection)
{
SqlCommand Command = new SqlCommand(Sql, SqlConnection);
//Command.CommandType = CommandType.StoredProcedure;
Command.Parameters.Add("TypeName", SqlDbType.NVarChar, 50).Value = typeName;
return Command;
}
}
}
DataSet 是一次性取表中数据 可能慢一些具体的哪个更合适 要看你的 需求
三层架构本身的设计原则就是高层依赖低层,逐层调用 ,不依赖具体依赖抽象~~ 换另外一个角度来说 ,datareader是持续连接的,按照楼主的意思,在获取数据后传递到高层的过程中,数据库连接是一直持续连接的,如果此时另有操作数据库,那么就会打开一个新的数据库连接,假如,只是假如,每一个操作都是datareader级操作,那楼主你认为你提到的效率跟一个ui界面持续链接N个数据库连接的资源消耗,哪个影响更大?更何况,现代计算机的配置
网上说 SQLHelper 不是不能实例化吗
SQLHelper helper = new SQLHelper();怎么这里???
赞同将其转化为List对象,然后进行接下来的操作
这样做是不会得到很大的提升的(可以忽略的)。
然而副作用却破坏了整个程序结构。为什么可以忽略呢?
虽然DataSet先使用了DataReader,
但是其中的操作也只是复制了一下内容,
这个是非常非常非常快的。无需操心。
如果非要的话 也许可以使用c#流对象来保存
不过这样好像也要保存 还是要复制 要不你程序哪里要用到数据是在那里创建datareader对象 直接用
如有说错 请见谅
有关实际的例子请参看:
http://blog.csdn.net/bluedoctor/archive/2010/01/24/5251913.aspx
DataReader是数据读取用的 ,
读出来的数据需要存放容器,如Dataset,datatable,IList等
你要传值,首先要有数据容器.
public static SqlDataReader GetReader(string sql)
{
SqlCommand cmd = new SqlCommand(sql, Conn);
return cmd.ExecuteReader();
}
DAOpublic IList<Class> GetClasslist()
{
List<Class> Class = new List<Class>();
StringBuilder strsql = new StringBuilder();
strsql.Append("select top 10 * from gg_sys_class");
SqlDataReader dr=DBhelpaer.GetReader(strsql.ToString());
if (dr.HasRows)
{
while (dr.Read())
{
Class.Add(SetClass(dr));
}
}
return Class;
} public Class SetClass(SqlDataReader reader)
{
Class sclass = new Class();
sclass.acadyear = reader["acadyear"].ToString();
sclass.artsciencetype = reader["artsciencetype"].ToString();
sclass.classid = reader["classid"].ToString();
//sclass.classintid = reader["classintid"].ToString();
sclass.classname = reader["classname"].ToString();
sclass.classno = reader["classno"].ToString();
sclass.classtype = reader["classtype"].ToString();
sclass.gradeid = reader["gradeid"].ToString();
sclass.schid = reader["schid"].ToString();
sclass.schooling_length =Convert.ToInt32( reader["schooling_length"]);
sclass.section = reader["section"].ToString();
//sclass.GradeName = reader["gradename"].ToString();
return sclass;
}
另外 手工和自动填dataset速度几乎没区别
如果你读取出来的是一个结果集,还是用DataAdapter快,不浪费数据库连接。
datareader在读取数据的过程中始终保持一个连接,直到你把它释放。
DataAdapter可以一次性读取数据到dataset释放连接,所以不浪费数据库连接。
如果你从数据库中得到的是一个值,如int或string
你可以用cmd.ExecuteScalar返回object,这是最快的
remoting没测过,你可以试试看
{
List<UserInfor> list = new List<UserInfor>();
SQLHelper helper = new SQLHelper();
string sql = "select * from UserInfor";
SqlParameter[] prams = null;
SqlDataReader sdr = helper.ExecuteDataReader(sql, prams);
while (sdr.Read())
{
UserInformodel = new UserInfor();
model.Username = sdr["Username"].ToString();
model.Usertype =sdr["Usertype"].ToString();
list.Add(model);
}
sdr.Close();
return list;
}UserInfor 是实体类, 用List<T> 传数据
参考答案来源于:topic.csdn.net我正在使用《Csdn收音机》第一时间获取最新动态!