网站导航网学 原创论文 原创专题 网站设计 最新系统 原创论文 论文降重 发表论文 论文发表 UI设计定制 论文答辩PPT格式排版 期刊发表 论文专题
返回网学首页
网学原创论文
最新论文 推荐专题 热门论文 论文专题
当前位置: 网学 > 设计资源 > .Net编程 > 正文

通过DataReader获取多个结果集

论文降重修改服务、格式排版等 获取论文 论文降重及排版 论文发表 相关服务

我们知道,ado.net的DataReader提供一种从数据库读取行的只进流的方式。通常情况下,我们都是针对一个结果集进行处理。其实通过DataReader的NextResult方法,我们可以批处理T-SQL,也就是可以获取处理两个或者多个结果集。下面通过一个简单的示例,来简单说明一下这个功能。

1、数据表
我们还是沿用这一篇里的Person表。在Person表里,我们定义了自增长的Id,姓、名、身高和体重,它们对应的字段和实体里的属性命名是一样的。

2、实体类

  1. public class Person 
  2.     public int Id { getset; } 
  3.     public string FirstName { getset; } 
  4.     public string LastName { getset; } 
  5.     public double Weight { getset; } 
  6.     public double Height { getset; } 
  7.  
  8.     /// <summary> 
  9.     /// 总记录数 
  10.     /// </summary> 
  11.     public long TotalCount { getset; } 

需要说明的是,TotalCount属性是我们自己根据统计需要,添加的用来统计符合条件的人的总记录数,并不是Person表的一个实际字段。

3、数据实体转换

  1. public class SqlHelper 
  2.     { 
  3.         private const string strSqlCon = @"Data Source=.\sqlexpress; Initial Catalog=TestDb; User Id=sa; Password=123456;"
  4.  
  5.         /// <summary> 
  6.         /// 数据表项转换为对应实体 (操作两个结果集 有总记录数) 
  7.         /// </summary> 
  8.         /// <typeparam name="T"></typeparam> 
  9.         /// <param name="objType"></param> 
  10.         /// <param name="strSelectSql"></param> 
  11.         /// <returns></returns> 
  12.         public static IList<T> Select<T>(Type objType, string strSelectSql) where T : classnew() 
  13.         { 
  14.             IList<T> listModels = new List<T>(); 
  15.             using (SqlConnection sqlConn = new SqlConnection(strSqlCon)) 
  16.             { 
  17.                 sqlConn.Open(); 
  18.                 SqlCommand cmd = new SqlCommand(); 
  19.                 cmd.Connection = sqlConn; 
  20.                 cmd.CommandText = strSelectSql; 
  21.                 IDataReader rdr = cmd.ExecuteReader(); 
  22.                 Hashtable htColumns = CreateHashColumnName(rdr); 
  23.  
  24.                 while (rdr.Read()) 
  25.                 { 
  26.                     Object obj = Activator.CreateInstance(objType); 
  27.                     PropertyInfo properties = objType.GetProperties(); 
  28.                     foreach (PropertyInfo propInfo in properties) 
  29.                     { 
  30.                         if (htColumns.Contains(propInfo.Name.ToUpper()) == false
  31.                         { 
  32.                             continue
  33.                         } 
  34.                         int index = rdr.GetOrdinal(propInfo.Name); 
  35.                         if (index > -1 && rdr.GetValue(index) != System.DBNull.Value) 
  36.                             propInfo.SetValue(obj, rdr.GetValue(index), null); 
  37.                     } 
  38.                     T model = default(T); 
  39.                     model = obj as T; 
  40.                     listModels.Add(model); 
  41.                 } 
  42.  
  43.                 bool isNext = rdr.NextResult();//前进到下一个结果集 
  44.                 htColumns = CreateHashColumnName(rdr);//改变hashtable的对应列名 
  45.                 while (rdr.Read() && isNext) 
  46.                 { 
  47.                     for (int i = 0; i < listModels.Count; i++) 
  48.                     { 
  49.                         PropertyInfo props = listModels[i].GetType().GetProperties(); 
  50.                         foreach (PropertyInfo pi in props) 
  51.                         { 
  52.                             if (htColumns.Contains(pi.Name.ToUpper()))//取总记录数 
  53.                             { 
  54.                                 int index = rdr.GetOrdinal(pi.Name); 
  55.                                 if (index > -1 && rdr.GetValue(index) != System.DBNull.Value) 
  56.                                     pi.SetValue(listModels[i], rdr.GetValue(index), null); 
  57.                                 break;//根据实际情况确定break需不需要注释掉 
  58.                             } 
  59.                         } 
  60.                     } 
  61.                 } 
  62.             } 
  63.             return listModels; 
  64.         } 
  65.  
  66.         private static Hashtable CreateHashColumnName(IDataReader rdr) 
  67.         { 
  68.             int len = rdr.FieldCount; 
  69.             Hashtable ht = new Hashtable(len); 
  70.             for (int i = 0; i < len; i++) 
  71.             { 
  72.                 string columnName = rdr.GetName(i).ToUpper(); //不区分大小写 
  73.                 string columnRealName = rdr.GetName(i); 
  74.                 if (ht.ContainsKey(columnName) == false
  75.                 { 
  76.                     ht.Add(columnName, columnRealName); 
  77.                 } 
  78.             } 
  79.             return ht; 
  80.         } 
  81.  
  82.     } 

上面的代码中,注释写的很清楚,通过NextResult方法后,我们再次获取结果集的列(示例中保持在hashtable里),利用第一次获得结果集的方法和原理,给实体赋值。

4、前台调用
很简单,通过一个带分号的sql语句,获得一个实体集合。

  1. //批量sql语句 以;隔开 
  2.            string sql = "SELECT TOP 10 [Id] ,[FirstName],[LastName],[Weight],[Height] FROM Person (NOLOCK); SELECT COUNT(Id) AS TotalCount FROM Person (NOLOCK) "
  3.            IList<Person> listPersons = SqlHelper.Select<Person>(typeof(Person), sql);//操作两个结果集 

有图有真相:



从图中我们可以清楚地看到,测试数据库里的总人数是1999918人。

最后,请教最近使用linq2sql一点困扰我的地方:很多人津津乐道的SkipTake分页(本质上据说就是二次top),好像无法直接取得总记录数(TotalCount),但是正常项目中都会通过总记录数确定分页效果。除了直接通过linq查询取Count之外,不知道大家有没有其他更好的方法,比如窗口函数row number,或者就像本文所表达的那样,批处理一次查询就搞定的那种?

设为首页 | 加入收藏 | 网学首页 | 原创论文 | 计算机原创
版权所有 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
Copyright 2008-2020 myeducs.Cn www.myeducs.Cn All Rights Reserved 湘ICP备09003080号 常年法律顾问:王律师