使用大量数据填充DataGridView的最佳方法

时间:2010-08-26 23:07:55

标签: c# datagridview

我有一个Windows窗体,它有两个DataGridViews(DGV),每个容纳25,000条记录和21列。我已经使用DataAdapter成功地从数据库加载了数据,然后我尝试使用for循环填充DGV。每种方法花费的时间大致相同。第一次将数据填入DGV时需要太长时间(7+分钟),然后随后的时间更合理(~30秒)。所以我的问题是,加载具有大量平均<= 1分钟的大量数据的DGV的最佳方法是什么?我非常喜欢DGV的功能,但是如果推动推动我愿意使用不同的技术,即使它意味着放弃一些功能。

6 个答案:

答案 0 :(得分:32)

基本上有3种方式可以在DataGridView

中显示数据
  • 在循环中手动创建行,正如您当前所做的那样:正如您所注意到的,如果您拥有大量数据,效率非常低

  • 使用DataGridView的虚拟模式,正如Jonathan在评论中所建议的那样:DGV只会创建尽可能多的行,并在用户滚动时动态更改其内容。您需要处理CellValueNeeded事件以向DGV提供所需数据

  • 使用数据绑定:这是迄今为止最简单的方法。您只需使用DataTableDbDataAdapter填充数据库中的数据,然后将此DataTable分配给DGV的DataSource媒体资源。 DGV可以自动创建列(AutoGenerateColumns = true),也可以手动创建(您必须将列的DataPropertyName设置为要显示的字段的名称)。在数据绑定模式下,DGV的工作方式与虚拟模式类似,只是它负责从数据源中获取数据,因此您无需执行任何操作。即使对于大量行

  • ,它也非常有效

答案 1 :(得分:6)

我认为您可以使用DataReader方法而不是DataAdapter。 DataReader是非常有效的单向组件,因为它只从源读取数据,并且您可以使用循环填充数据表。

答案 2 :(得分:2)

如果您有大量的行,例如10 000或更多,

以避免性能泄漏 - 在数据绑定之前执行以下操作:

dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.EnableResizing; 
//or even better .DisableResizing. 
//Most time consumption enum is DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders
dataGridView1.RowHeadersVisible = false; // set it to false if not needed

数据绑定后,您可以启用它。

答案 3 :(得分:1)

尝试使用DataTable。填充。 然后使用DataView。将其分配给DataGridView DataSource。

//DataView dataView = new DataView(dataTable);
//this.Grid.DataSource = dataView;

对于大文件(一秒钟内有25000条记录和21列),您将获得非常小的响应时间。 我的模板程序需要7秒才能加载100 000行* 100列 {有愚蠢的内容 - &gt;行号为字符串}

答案 4 :(得分:1)

这解决了我的问题:

gsub

答案 5 :(得分:0)

我不确定这是你要求的,但我喜欢创建一个数据子集来进行内部加载,然后包含搜索功能。 使用visual studio 15和DataSources / data set非常容易。 在解决方案资源管理器中,打开您的dataset.xsd文件。它将命名为DataSet.xsd 转到相关数据表。单击鼠标右键,然后添加查询。我通常做的一件事就是在我的查询中添加“TOP 1000”。 因此,从mytable中选择*将从mytable

中选择TOP 1000 *

最后,双击表单以查找_load方法,并更改“填充”以使用新查询。通过示例可以最好地证明这一点:

我注释掉的第一行代码是Vis Stud默认创建的代码。 第二个是我添加的,它只会获得前1000个记录。

function display(width, height){
  this.width = width * 2;
  this.height = height * 2;
}

function position(x, y){
  this.x = x;
  this.y = y;
}

function initialize(){
  for(var x = circlePosition.length; x < circleCount; x++){
    circlePosition[x] = new position(Math.random() * (resolution.width - (-resolution.width)) + (-resolution.width), Math.random() * (resolution.height - (-resolution.height)) + (-resolution.height));
    
  }
}

socket.on('display',
      function(data) {
        resolution = new display(data.width, data.height);
        initialize();
        io.sockets.emit('positioning', circlePosition);
      });