平时 数据都是用实体类 或者ILIST<实体类>所以涉及到一个 数据转换为实体~请问只是用来转换为实体对象 或者LIST<实体类> 集合  用 datareader 好 还是  dataset好呢~  说下原因 谢谢~~datareader 只读向前 速度快 可是周公 这篇文章 测试发现 http://zhoufoxcn.blog.51cto.com/792419/614794datatable 快~  问问大家平时用的哪个~ 谢谢

解决方案 »

  1.   

    datareader会一条条读,dataset会把所有的数据加载到内存,你看情况使用就是了
      

  2.   


    多谢~~ 目前我也是使用的  dataset~
      

  3.   

    datareader,数据越多越有速度优势
      

  4.   

    datareader记得close,未关闭前不能获得存储过程返回值
      

  5.   

    一般不涉及到分页,我都用sqldatareader,分页就会用dataset
      

  6.   

    刚才闲来没事看了下网站代码,他的测试代码本身是有问题的。对datatable的测试没有包含fill 的时间。这个其实是最耗时的,对datareader的测试则包含了从数据库读取到实例化两部分时间。对通用helper 使用reader是首选。
      

  7.   

    其实博客的文章也只是做为你的参考,并不能成为依据。习惯使用dataset,数据多就用分页存储过程啦。
      

  8.   

    DataSet 和 datareader  都会用到  个人觉得速度不是很大区别。
    datareader  要注意关闭 看个人爱好习惯吧。  
      

  9.   

    数据量大的时候datareader会有优势,小的时候看个人爱好了不过你要是转换成实体类,个人觉的DataReader应该会好点,不然你用DataTable接受数据后,还要循环赋给实体
      

  10.   

    简单看了一下博客的意思,我想许多人把读取DataReader成对象想象得太复杂了。这根本用不着反射,以及很多的switch判断,反射会让你的程序慢的不是一星半点(而是巨大),所以虽然你知道反射、研究反射,但是应该尽量做到几乎从来不使用反射。将DbDataReader转换为对象实体,我们定义一个接口就行了public interface IConverterFromDbDataReader<T>
    {
        void Convert(DbDataReader reader, T obj);
    }而你的BLL内部的需要从DataReader读取出实体的对象就都可以实现这个接口,例如我随便举一个例子:public class FileTransferBlock : IConverterFromDbDataReader<FileTransferBlock>
    {
        public long CallID;
        public string SourceFile;
        public string TargetFile;
        public long StartPosition;    public void Convert(DbDataReader reader, FileTransferBlock obj)
        {
            obj.CallID = (long)reader["call_id"];
            obj.SourceFile = (string)reader["source"];
            obj.TargetFile = (string)reader["target"];
            obj.StartPosition = (long)reader["position"];
        }
    }
    这个例子清楚地说明了,如何将DataReader轻松地转换到对象的字段(或者属性)上。这并不增加多少工作量,因为你平常使用SqlHelper之类的来得到对象、或者从某种离散的一堆列值中得到对象时做的工作绝对不比这个更少。剩下的SqlHelper中工作就非常清楚了,比如说它可能是这样写的static public List<T> GetRecords<T>(string sql, params DbParameter[] para) where T : IConverterFromDbDataReader<T>, new()
    {
        using (DbConnection conn = CreateNewConnection())
        {
            conn.Open();
            var comm = conn.CreateCommand();
            comm.CommandText = sql;
            comm.Parameters.AddRange(para);
            var reader = comm.ExecuteReader();
            var result = new List<T>();
            while (reader.Read())
            {
                var obj = new T();
                obj.Convert(reader, obj);
                result.Add(obj);
            }
            return result;
        }
    }
    那么我们直接调用 GetRecords<FileTransferBlock>(sqlString,null) 就能得到一个 FileTransferBlock 对象集合了。
    上述,是因为这里讨论到比较底层的SqlHelper的写法。但是我的重点不单单是关于这个写法,我要强调的是:不要随便使用反射,而且大多数时候你也根本不需要使用反射!
      

  11.   

    嗯当然,我们可以把接口里的那个方法写的更简单一点public interface IConverterFromDbDataReader<T>
    {
        void ConvertFrom(DbDataReader reader);
    }public class FileTransferBlock : IConverterFromDbDataReader<FileTransferBlock>
    {
        public long CallID;
        public string SourceFile;
        public string TargetFile;
        public long StartPosition;    public void ConvertFrom(DbDataReader reader)
        {
            this.CallID = (long)reader["call_id"];
            this.SourceFile = (string)reader["source"];
            this.TargetFile = (string)reader["target"];
            this.StartPosition = (long)reader["position"];
        }
    }static public List<T> GetRecords<T>(string sql, params DbParameter[] para) where T : IConverterFromDbDataReader<T>, new()
    {
        using (DbConnection conn = CreateNewConnection())
        {
            conn.Open();
            var comm = conn.CreateCommand();
            comm.CommandText = sql;
            comm.Parameters.AddRange(para);
            var reader = comm.ExecuteReader();
            var result = new List<T>();
            while (reader.Read())
            {
                var obj = new T();
                obj.ConvertFrom(reader);
                result.Add(obj);
            }
            return result;
        }
    }
      

  12.   

    那个博客根本就是误导人的,adapter.Fill都不计算在耗时内那测试还有什么意义。实际上adapter.Fill也是通过datareader来读取数据库的。
      

  13.   

    博客中一开头实际要测试的是一个针对DataTable,另一个针对DbDataReader,仅仅对比这两个结构进行对象转换的时间。而它写了测试前者的时间的代码,并没有写后者的。并且它针对后者,使用的是反射方式。当然也确实,文章一开头看起来还是清楚表明了是要比较DataTable和DbDataReader转换为对象的方法测试。但是文章最后的实际测试却把它作为比较读取数据库记录成为对象的整体测试的结论来做总结了,而整体时间没有包括Fill方法和ExecuteReader的时间。不过我们想象一下,就算包括了这两段时间,结论会改变吗?因为文章虽然结论不对,但是测试数据没有骗人,仍然可以说明:基于反射进行大量GetValue、SetValue的代码的性能往往是很差的。请搜索一下代码中的“row[item.Key]”这个语句,这里是关键,这条语句不是使用反射,而是使用DataRow的从列中搜索的方式。因此我会写上面的内容,来个直截了当的也不反射的 ConvertFrom 设计来对比一下。
      

  14.   

    习惯实用dataset 但是datareader 要注意关闭  close
      

  15.   


    这个说法是不对的!仅仅对于设置 CommandBehavior 为 CloseConnection 的 SqlDataReader 对象实例,并且当它已经离开了 Connection 控制变量的作用域(也就是说你的代码不可能去对其执行 Close()操作),你才需要通过执行 reader.Close() 来关闭Connection。其它的都是多余的,额外地占用了时间。通用的DbDataReader根本没有 CommandBehavior,那么也根本没有这个机制。而就算是针对SqlDataReader,你也只有机器特定的情况下才有必要去想着调用其 Close() 方法。
      

  16.   


    他从DataTable转换为对象也是通过反射的,所以最后结果应该还是用DataReader快一些,当然差别是很小的。
    单单比较DataTable和DbDataReader没意义,因为DataTable跟数据库完全无关,只是存放的从DbDataReader读取的数据
      

  17.   

    其实是相对来说的。如果数据量读取大的话,datareader要好。由于dataset它要读到内存中,相对于现在来说内存比较大,配置高,你感觉不出来,肯定觉得它不影响了。dataset感觉读取数据方便,可以随意取。还可以存取多表吧!
      

  18.   

    它使用了 row[item.Key] 来避免 GetValue 语句。所以你看,即使仍然使用 SetValue 语句来反射设置对象属性(而不是说哦那个Convert一举两得),测试数据也已经说明,“有一个数量级的速度差别”(原文的结论)。
      

  19.   

    或者这样说吧,假设它的结论是成立的,既避免GetValue语句就可以提高10倍速度,那么我们几乎可以猜测,完全不使用反射的SetValue语句,从DbDataReader取得目标对象,最终测试结果可以提高几乎100倍的速度。