在带有定位器的DataGridView中显示来自WCF的大量记录

本文关键字:WCF 记录 定位器 DataGridView 显示 | 更新日期: 2023-09-27 17:50:35

我有一个基于Clarion TPS的商业软件,我想用c#编写的软件替换它,使用以下技术:

    SQL Server 2008 R2 Express
  • EntityFramework 4
  • WCF服务与wsHttpBinding和基于消息的安全使用UserNamePassword凭据
  • Windows窗体客户端

Clarion软件使用TPS文件作为数据库表。TPS数据库文件使用ISAM文件格式,允许将所有索引和多个数据文件包含在一个磁盘文件中。这种方法的优点是非常快的记录访问,然而主要的缺点是当多个客户端访问时,数据库损坏的可能性很大,并且表中数据不一致的可能性很大。

我想替换它,因为我想更好地控制我的数据库访问(例如谁可以访问什么),我不想让客户端直接访问数据库,我发现WCF服务是完美的任务。

这在理论上都很好,但是实际的使用场景让我暂时放弃了实现它。例如,当我打开一个对话框与Datagridview需要显示一个相对较大的记录列表(约20,000),它需要~10秒来显示。在《号角》中,这是即时发生的。Clarion有一个叫做"定位器"的功能,它允许你通过输入那些记录属性的字母来定位记录。名称)以。

我知道在WCF上数据的序列化和反序列化需要一些时间。至于序列化,我已经优化了代码,使WCF服务使用DataContractSerializer(具有循环引用感知行为)。我已经将EF生成的默认实体更改为POCO实体,使用EF POCO实体生成器。我已经添加了预编译的视图,我的WCF服务返回的对象被称为"ViewModels",而不是POCOs,我认为这是必需的。

我已经创建了一些类似于Clarion的"定位器"行为的东西,它看起来像这样:

private void locator_TextChanged(System.Object sender, System.EventArgs e)
{
    if (!string.IsNullOrWhiteSpace(locator.Text))
    {
        for (int idx = 0; idx <= dataGrid1.RowCount - 1; idx++)
        {
            var row = dataGrid1.Rows[idx];
            if ((row.DataBoundItem != null) && ((SomeViewModel)row.DataBoundItem).Name.ToUpper().StartsWith(locator.Text.ToUpper()))
            {
                row.Cells[0].Selected = true;
                break;
            }
        }
    }
}

它可以很好地处理几百甚至几千条记录。但是由于大量的记录,看起来和感觉都很糟糕。当您看到代码时,您可能已经猜到了。这样也不会更快:

if (!string.IsNullOrWhiteSpace(locator.Text)) {
    var r = dataGrid1.Rows.Cast<DataGridViewRow>().FirstOrDefault(x => ((SomeViewModel)(x.DataBoundItem)).PrezimeIme.ToUpper().StartsWith(locator.Text.ToUpper()));
    if (r != null) 
    {
        r.Cells[0].Selected = true;
    }
}

这个问题。如果我们知道我使用了上面列出的那些技术,如何模仿Clarion将如此多的记录快速加载到datagridview中的速度?

在带有定位器的DataGridView中显示来自WCF的大量记录

Clarion TPS文件在多个程序访问时不会损坏,因为它们使用文件锁定协议。如果他们通过使用机会锁定(oplocks)的文件共享访问,因为锁/解锁的顺序可能会被扭曲,或者如果您有任何运行Microsoft Security Essentials的客户端(它有一个混合锁/解锁顺序的"功能",不,它不会被修复),但除此之外,它工作得"很好"。

你的代码慢的原因是因为它必须遍历文件中的所有行,这很慢,因为它是所有的磁盘I/O和Clarion不做任何缓存。

要访问数据,您可以:1)使用此工具将TPS文件转换为CVS,并将其导入SQL数据库。这个问题以前已经在这里回答过了。

2)从SoftVelocity购买TPS- odbc驱动程序,通过SQL查询访问TPS文件。TPS驱动程序有一些奇怪的地方,您需要一个函数来转换日期和时间,您不能访问大的内存,一些查询可能返回的行数少于TPS文件包含的行数(取决于您的主键是如何构造的),并且您必须在所有文件中有一个唯一的主键。这与直接访问文件一样快/慢,所以我建议只使用这种方法将数据导出到MSSQL数据库。

还有一些工具可以通过将DCT导出为文本文件(dtcx)来将Clarion DCT转换为SQL,您还可以通过将表类型从TPS更改为MSSQL来使Clarion生成结构。

看起来您正在遍历所有记录,但Clarion代码从文件索引中获得新位置。