首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Compact vs SqlDataAdapter

Compact vs SqlDataAdapter
EN

Stack Overflow用户
提问于 2015-12-04 18:32:01
回答 1查看 438关注 0票数 0

我正在开发一个较旧的应用程序,它与运行Server和.Net 3.5的手持扫描仪设备一起工作。

我的问题与使用SqlCeDataReaderSqlCeDataAdapter之间的性能有关。我读到的很多文章都指出,DataReaderDataAdapter快得多,因为它的开销要小得多,并且一次直接记录一条,而不是大量“填充”到datatable或DataSet中。

现有的应用程序使用的是DataAdapter,我正在尝试对DataReader进行改造,但在手持设备上找到DataReader的速度更慢,这完全让我感到困惑。

总之,这是一个简化的版本,其他帖子也有类似的。

创造桌子..。45个字段,而不仅仅是3或4个字段样本

代码语言:javascript
复制
// Showing more fields just to show variety of columns of not just
// strings, but of other types too   
CREATE TABLE MyTest 
(
   MyTestID     int IDENTITY(1,1) CONSTRAINT MyTestID PRIMARY KEY,
   Fld1    int,
   Fld2    int, 
   ... (more, just stripped for sample)
   fld6    float,
   Fld7    nchar(2),
   Fld8    float,
   Fld9    nchar(2),
   Fld10   int,
   ... (more, just stripped for sample)
   Fld24   DATETIME, 
   Fld25   nchar(1), 
   Fld26   nchar(15), 
   Fld27   nvarchar(15), 
   ... (more, just stripped for sample)
   Fld44   DATETIME, 
   Fld45   int )

之后,我有一个类,其最基本的格式是

代码语言:javascript
复制
public class CTypedClass1
{
   public int Fld1 { get; set; }
   public int Fld2 { get; set; }
   ... etc..
   public double Fld6 { get; set; }
   public double Fld7 { get; set; }
   public string Fld8 { get; set; }
   ... etc to field 45
}

然后,我有两种方法,循环到100条记录的计数中,相应地调用数据适配器与DataReader之间的查询方法。

代码语言:javascript
复制
private void ReadMyTestByAdapter()
{
   var cmd = MyConnection.GetSQLDbCommand( "Select * from MyTest where MyTestID = @nMyTestParm" );
   cmd.Parameters.Add( "nMyTestParm", 1 );
   var da = MyConnection.GetSQLDataAdapter();
   da.SelectCommand = cmd;

   for (int i = 1; i < 100; i++)
   {
      DataTable tmpTbl = new DataTable();
      da.SelectCommand.Parameters[0].Value = i;
      QueryByDataAdapter(da, tmpTbl);
   }
}

private void ReadMyTestByTypedClass()
{
   var cmd = MyConnection.GetSQLDbCommand("Select * from MyTest where MyTestID = @nMyTestParm");
   cmd.Parameters.Add("nMyTestParm", 1);

   for (int i = 1; i < 100; i++)
   {
      CTypedClass1 tmpRec = new CTypedClass1();
      cmd.Parameters[0].Value = i;
      QueryByStruct(cmd, tmpRec);
   }
}

现在,通过数据适配器进行查询,并将结果填充到DataTable中。

代码语言:javascript
复制
private void QueryByDataAdapter(SqlCeDataAdapter da, DataTable putInHere )
{
   if (da.SelectCommand.Connection.State != ConnectionState.Open)
      da.SelectCommand.Connection.Open();

   da.Fill(putInHere);

   if (da.SelectCommand.Connection.State == ConnectionState.Open)
      da.SelectCommand.Connection.Close();
}

为了防止反射开销,我尝试使用数据读取器直接进入类型化类的属性。

代码语言:javascript
复制
private void QueryByStruct(SqlCeCommand cmd, CTypedClass1 curRec)
{
   if (cmd.Connection.State != ConnectionState.Open)
      cmd.Connection.Open();

   using (var reader = cmd.ExecuteReader())
   {
      while (reader.Read())
      {
         curRec.Fld1 = (int)reader["Fld1"];
         curRec.Fld2 = (int)reader["Fld2"];
         // etc with rest of fields to 45
         // all explicitly (typecast) referenced
      }
   }

   if (cmd.Connection.State == ConnectionState.Open)
      cmd.Connection.Close();
}

该过程实际上完成了表的所有45个字段,这两个方法之间的性能在9秒内几乎相同,可以读取100条记录,每次都单独查询一个ID。类型化格式所使用的表形内存小于DataTable/DataAdapter的内存,而DataTable /DataAdapter也令人困惑,因为类型化只存储值的一个实例,但是DataTable结果在行级别拥有整个ItemArray,并且具有当前值、默认值和原始值的DataRowVersion。

这是没有任何意义的,希望有人能给我一点启示。

注意:如果我在桌面计算机上做同样的事情(针对不同的数据库,但是连接、查询等是相同的),类型化类方法的速度大约是数据适配器方法的6倍。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-04 19:24:13

在我的经验中使用reader[string]很慢。当我在HandHeld扫描仪上为CE开发时,我使用了如下内容:(不要使用DataAdapter,它更慢)

代码语言:javascript
复制
private void QueryByStruct(SqlCeCommand cmd, CTypedClass1 curRec)
{
   if (cmd.Connection.State != ConnectionState.Open)
      cmd.Connection.Open();

   List<object> fields;

   using (var reader = cmd.ExecuteReader())
   {
      if (reader.Read())
      {
          var values = new Object[reader.FieldCount];
          reader.GetValues(values);
          fields = values.ToList();
      }
   }

   if (cmd.Connection.State == ConnectionState.Open)
      cmd.Connection.Close();

   curRec.Fld1 = (int)fields.ElementAt(1);
   curRec.Fld2 = (int)fields.ElementAt(2);
   // etc with rest of fields to 45
   // all explicitly (typecast) referenced

}

我将while更改为if,因为看起来您只是在覆盖值,没有什么好的理由。在我的经验中,GetValues()真的非常快。缺点是,您只按列顺序获得值,没有列类型或列名。

还有一个好的-终极性能调优:

视频通道

终极性能调优Powerpoint演示文稿(直接链接)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34095122

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档