• DataReader和DataAdapter的区别


    SqlDataReader是一个向前的指针,本身并不包含数据,调用一次Read()方法它就向前到下一条记录,一个SqlDataReader必须单独占用一个打开的数据库连接。

    在使用 SqlDataReader时,关联的 SqlConnection 正忙于为 SqlDataReader 服务,对 SqlConnection 无法执行任何其他操作。除非调用 SqlDataReader 的 Close 方法,否则会一直处于此状态。

    SqlDataAdapter象一座桥梁,一头连起数据库表,一头连起一个 DataSet 或者 DataTable ,在把数据库中的数据填充到 DataSet 或 DataTable 后就可以“过河拆桥”,不用再连接到数据库,而可以直接从 DataSet 或 DataTable 中获取数据。

    SqlDataAdapter提供了许多的方法,来方便我们对一些特定的数据集合进行操作比如,填充一个查询结果到 DataTable ,或 DataSet 中其实就是类似于:创建一个 SqlCommand 然后执行 "Select * from [Table]" 然后执行 ExcuteReader()方法 得到一个IDataReader对象然后逐行读取数据并存放到一个集合对象中(如DataTable)经过测试,如果有大量的数据操作最好是自己写 SqlCommand ,会比SqlDataAdapter操作数据库快很多

    SqlDataReader只能读取数据库,而且所操作的表必须处于连接状态,但是要对数据库进行写操时,只能借助 SqlCommand 类,SqlDataAdapter 它建立在 SqlCommand 对象之上,它具有 SqlCommand 类的一切功能,能够将数据填充到 DataSet 对象中,而且不用再连接到数据库,而可以直接从 DataSet 或 DataTable 中获取数据。(因为它采用的无连接传输模式)

    SqlDataReader对象可以从数据库中得到只读的、只能向前的数据流,还可以提高应用程序的性能,减少系统开销,同一时间只有一条行记录在内存中。

    SqlDataAdapter对象可以自动打开和自动关闭数据库连接(不需人为管理),适配器的主要工作流程:SqlConnection 对象建立与数据源的连接,SqlDataAdapter 对象经由 SqlCommand 对象返回给SqlDataAdapter,最后将SqlDataAdapter对象加入到 DataSet 对象的 DataTables 对象中。

    总结:

    性能上:SqlDataReader一次只在内存中存储一行,减少了系统开销。优于SqlDataAdapter。

    读取时:SqlDataReader需通过调用自身Read()方法循环读取数据到指定对象。而SqlDataAdapter可通过调用Fill()方法一次性填充数据到DataSet。还可将对 DataSet 所做的更改解析回数据源。

    操作上:SqlDataReader需通过调用自身的Close()方法断开连接。而SqlDataAdapter可以读取完数据库后自动断开连接.

               var sql = "SELECT *  FROM  BOARD_VEHICLE_DAY_INFO  WHERE PASSKEY='湘ALM2DA-2-2019年10月15日' ";
     DataTable result = new DataTable();
    //ExecuteReader using (OracleConnection conn = new OracleConnection("Data Source=zhzepp;User Id=jxlx;Password=citms;")) { conn.Open(); //创建命令对象,前面一个表示执行的语句,后面一个表示执行语句需要连接的数据库 OracleCommand cmd = new OracleCommand(sql, conn); //创建查询的结果集,用另一个封装的方法,ExecuteReader OracleDataReader read = cmd.ExecuteReader(); result.Load(read); }
    //OracleDataAdapter using (OracleConnection conn = new OracleConnection("Data Source=zhzepp;User Id=jxlx;Password=citms;")) { conn.Open(); //创建命令对象,前面一个表示执行的语句,后面一个表示执行语句需要连接的数据库 OracleCommand cmd = new OracleCommand(sql, conn); OracleDataAdapter adapter = new OracleDataAdapter(cmd); adapter.Fill(result); }

     使用20万条数据进行测试

    ExecuteReader耗时50秒,
    OracleDataAdapter耗时11秒
    测试如下
     Stopwatch watch = Stopwatch.StartNew();
                watch.Start();
    
                List<BOARD_VEHICLE_DAY_INFOEntity> list = new List<BOARD_VEHICLE_DAY_INFOEntity>();
                List<BOARD_VEHICLE_DAY_INFOEntity> list1 = new List<BOARD_VEHICLE_DAY_INFOEntity>();
                List<BOARD_VEHICLE_DAY_INFOEntity> list2 = new List<BOARD_VEHICLE_DAY_INFOEntity>();
                List<BOARD_VEHICLE_DAY_INFOEntity> list3 = new List<BOARD_VEHICLE_DAY_INFOEntity>();
                Task wt1 = Task.Run(() =>
                {
                    list1 = test1();
                    list.AddRange(list1);
                });
                Task wt2 = Task.Run(() =>
                {
                    list2 = test2();
                    list.AddRange(list2);
                });
                Task wt3 = Task.Run(() =>
                {
                    list3 = test3();
                    list.AddRange(list3);
                });
                var wtasks = new Task[] { wt1, wt2, wt3 };
                Task.WaitAll(wtasks);
                watch.Stop();
                Console.WriteLine($"耗时:{watch.ElapsedMilliseconds},总数:{list.Count}");
                Console.ReadKey();
     static private List<BOARD_VEHICLE_DAY_INFOEntity> test1()
            {
                List<BOARD_VEHICLE_DAY_INFOEntity> list = new List<BOARD_VEHICLE_DAY_INFOEntity>();
                DataTable result = new DataTable();
                var sql = "SELECT *  FROM  BOARD_VEHICLE_DAY_INFO  WHERE PASSKEY LIKE '豫%' ";
                //ExecuteReader
                using (OracleConnection conn = new OracleConnection("Data Source=zhzepp;User Id=jxlx;Password=citms;"))
                {
                    conn.Open();
                    //创建命令对象,前面一个表示执行的语句,后面一个表示执行语句需要连接的数据库
                    OracleCommand cmd = new OracleCommand(sql, conn);
                    //创建查询的结果集,用另一个封装的方法,ExecuteReader
                    //OracleDataReader read = cmd.ExecuteReader();
                    //result.Load(read);
                    OracleDataAdapter adapter = new OracleDataAdapter(cmd);
                    adapter.Fill(result);
                    conn.Close();
                    list = ConvertToModel<BOARD_VEHICLE_DAY_INFOEntity>(result);
                }
                return list;
            }
            static private List<BOARD_VEHICLE_DAY_INFOEntity> test2()
            {
                List<BOARD_VEHICLE_DAY_INFOEntity> list = new List<BOARD_VEHICLE_DAY_INFOEntity>();
                DataTable result = new DataTable();
                var sql = "SELECT *  FROM  BOARD_VEHICLE_DAY_INFO  WHERE PASSKEY  LIKE '湘%' ";
                //ExecuteReader
                using (OracleConnection conn = new OracleConnection("Data Source=zhzepp;User Id=jxlx;Password=citms;"))
                {
                    conn.Open();
                    //创建命令对象,前面一个表示执行的语句,后面一个表示执行语句需要连接的数据库
                    OracleCommand cmd = new OracleCommand(sql, conn);
                    //创建查询的结果集,用另一个封装的方法,ExecuteReader
                    //OracleDataReader read = cmd.ExecuteReader();
                    //result.Load(read);
                    OracleDataAdapter adapter = new OracleDataAdapter(cmd);
                    adapter.Fill(result);
                    conn.Close();
                    list = ConvertToModel<BOARD_VEHICLE_DAY_INFOEntity>(result);
                }
                return list;
            }
            static private List<BOARD_VEHICLE_DAY_INFOEntity> test3()
            {
                List<BOARD_VEHICLE_DAY_INFOEntity> list = new List<BOARD_VEHICLE_DAY_INFOEntity>();
                DataTable result = new DataTable();
                var sql = "SELECT *  FROM  BOARD_VEHICLE_DAY_INFO  WHERE PASSKEY  LIKE '鄂%' ";
                //ExecuteReader
                using (OracleConnection conn = new OracleConnection("Data Source=zhzepp;User Id=jxlx;Password=citms;"))
                {
                    conn.Open();
                    //创建命令对象,前面一个表示执行的语句,后面一个表示执行语句需要连接的数据库
                    OracleCommand cmd = new OracleCommand(sql, conn);
                    //创建查询的结果集,用另一个封装的方法,ExecuteReader
                    //OracleDataReader read = cmd.ExecuteReader();
                    //result.Load(read);
                    OracleDataAdapter adapter = new OracleDataAdapter(cmd);
                    adapter.Fill(result);
                    conn.Close();
                    list = ConvertToModel<BOARD_VEHICLE_DAY_INFOEntity>(result);
                }
                return list;
            }
            /// <summary>
            /// 将DataTable数据源转换成实体类
            /// </summary>
            public static List<T> ConvertToModel<T>(DataTable dt) where T : new()
            {
                List<T> ts = new List<T>();// 定义集合
                foreach (DataRow dr in dt.Rows)
                {
                    T t = new T();
                    PropertyInfo[] propertys = t.GetType().GetProperties();// 获得此模型的公共属性
                    foreach (PropertyInfo pi in propertys)
                    {
                        if (dt.Columns.Contains(pi.Name))
                        {
                            if (!pi.CanWrite) continue;
                            var value = dr[pi.Name];
                            try
                            {
                                if (value != DBNull.Value && value != null && value.ToString() != "")
                                {
                                    if (pi.PropertyType.FullName.ToUpper().Contains("DECIMAL"))
                                    {
                                        pi.SetValue(t, decimal.Parse(value.ToString()), null);
                                    }
                                    else if (pi.PropertyType.FullName.ToUpper().Contains("DOUBLE"))
                                    {
                                        pi.SetValue(t, double.Parse(value.ToString()), null);
                                    }
                                    else if (pi.PropertyType.FullName.ToUpper().Contains("INT32"))
                                    {
                                        pi.SetValue(t, int.Parse(value.ToString()), null);
                                    }
                                    else if (pi.PropertyType.FullName.ToUpper().Contains("INT16"))
                                    {
                                        pi.SetValue(t, short.Parse(value.ToString()), null);
                                    }
                                    else
                                        pi.SetValue(t, value, null);
    
                                }
                            }
                            catch (Exception ex)
                            {
                                //throw ex;
                            }
    
                        }
                    }
                    ts.Add(t);
                }
                return ts;
            }
  • 相关阅读:
    蓝桥杯_基础训练_龟兔赛跑预测
    大数加法
    Splay!
    topsort
    各种方法
    有时候dfs可以简化各种组合的操作
    组合数学
    重新认识三观
    手速狗还是不行啊。。。
    set和map和pair 转自ACdreamers
  • 原文地址:https://www.cnblogs.com/macT/p/11759493.html
Copyright © 2020-2023  润新知