欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

数据库查询 - DataTable转Entity类型数据

程序员文章站 2022-05-03 22:14:13
使用LinqDB查询Sqlite数据库数据,不管是大数据还是少量的数据,感觉特别耗时,尤其是首次查询 一个含有2.7万条数据的数据表 首次查询: 查询2.7万条数据,耗时1s 查询指定的1条数据,也要耗时750ms 二次查询: 查询2.7万条数据,耗时475ms 查询指定的1条数据,耗时73ms 我 ......

使用linqdb查询sqlite数据库数据,不管是大数据还是少量的数据,感觉特别耗时,尤其是首次查询

一个含有2.7万条数据的数据表

首次查询:

  • 查询2.7万条数据,耗时1s
  • 查询指定的1条数据,也要耗时750ms

二次查询:

  • 查询2.7万条数据,耗时475ms
  • 查询指定的1条数据,耗时73ms

我们来尝试优化一下,使用sql语句查询

sql查询数据库

sql连接字符串:

1     var dbrelativepath = "dbs\\englishdict.db3";
2     var connectionstring = "data source=" + system.environment.currentdirectory + "\\" + dbrelativepath + ";version=3;";

sql查询,返回dataset集合

 1    /// <summary>
 2     /// 获得数据列表
 3     /// </summary>
 4     public dataset getlist(string strwhere, string tablename)
 5     {
 6         stringbuilder strsql = new stringbuilder();
 7         strsql.append("select * ");
 8         strsql.append($" from {tablename} ");
 9         if (strwhere.trim() != "")
10         {
11             strsql.append(" where " + strwhere);
12         }
13         return query(strsql.tostring());
14     }
15     /// <summary>
16     /// 执行查询语句,返回dataset
17     /// </summary>
18     /// <param name="sqlstring">查询语句</param>
19     /// <returns>dataset</returns>
20     public dataset query(string sqlstring)
21     {
22         using (sqliteconnection connection = new sqliteconnection(connectionstring))
23         {
24             dataset ds = new dataset();
25             try
26             {
27                 connection.open();
28                 sqlitedataadapter command = new sqlitedataadapter(sqlstring, connection);
29                 command.fill(ds, "ds");
30             }
31             catch (system.data.sqlite.sqliteexception ex)
32             {
33                 throw new exception(ex.message);
34             }
35             return ds;
36         }
37     }

dataset数据集转数据列表

1. 使用反射,映射到entity数据类中

见 数据库查询 - datatable转entity类型数据

 1     /// <summary>
 2     /// 获得数据列表
 3     /// </summary>
 4     public list<coursewareinfo> getcoursewares()
 5     {
 6         dataset ds = getlist(string.empty, "courseware");
 7         //通过映射,dataset转实体类
 8         var modellist = datatableconverter<coursewareinfo>.tolist(ds.tables[0]);
 9         return modellist;
10     }
11     /// <summary>
12     /// 获得数据列表
13     /// </summary>
14     public list<coursewareinfo> getcoursewares(string querytext)
15     {
16         var querystring = $"name like '%{querytext}%'";
17         dataset ds = getlist(querystring, "courseware");
18         //通过映射,dataset转实体类
19         var modellist = datatableconverter<coursewareinfo>.tolist(ds.tables[0]);
20         return modellist;
21     }

我们来看下查询数据的性能,还是同一数据表

首次查询:

  • 查询2.7万条数据,耗时1612ms
  • 查询指定的1条数据,也要耗时196ms

二次查询:

  • 查询2.7万条数据,耗时1484ms 
  • 查询指定的1条数据,耗时59ms

此方案耗时较多,应该是反射伤性能,放弃

2. 直接给数据类字段属性赋值

datatable转数据类:

 

 1         /// <summary>
 2         /// 将datatable转换成entity列表
 3         /// </summary>
 4         /// <param name="dt"></param>
 5         /// <returns></returns>
 6         public list<coursewareinfo> convertdttomodellist(datatable dt)
 7         {
 8             list<coursewareinfo> list = new list<coursewareinfo>();
 9             foreach (datarow dr in dt.rows)
10             {
11                 list.add(datarowtomodel(dr));
12             }
13             return list;
14         }
15         /// <summary>
16         /// 得到一个对象实体
17         /// </summary>
18         public coursewareinfo datarowtomodel(datarow row)
19         {
20             coursewareinfo model = new coursewareinfo();
21             if (row != null)
22             {
23                 model.localid = row["localid"].tostring();
24                 model.remoteid = row["remoteid"].tostring();
25                 model.name = row["name"].tostring();
26             }
27             return model;
28         }

获取数据列表:

 1     /// <summary>
 2     /// 获得数据列表
 3     /// </summary>
 4     public list<coursewareinfo> getcoursewares()
 5     {
 6         dataset ds = getlist(string.empty, "courseware");
 7         //通过字段赋值,dataset转实体类
 8         var modellist = convertdttomodellist(ds.tables[0]);
 9         return modellist;
10     }
11     /// <summary>
12     /// 获得数据列表
13     /// </summary>
14     public list<coursewareinfo> getcoursewares(string querytext)
15     {
16         var querystring = $"name like '%{querytext}%'";
17         dataset ds = getlist(querystring, "courseware");
18         //通过字段赋值,dataset转实体类
19         var modellist = convertdttomodellist(ds.tables[0]);
20         return modellist;
21     }

来看下查询数据的性能,还是同一数据表

首次查询:

  • 查询2.7万条数据,耗时660ms
  • 查询指定的1条数据,也要耗时191ms

二次查询:

  • 查询2.7万条数据,耗时500ms
  • 查询指定的1条数据,耗时58ms

此方案,数据查询性能很明显的改善。

 

总结:相对lindb,使用sql查询方案查询数据性能会好很多