使用定位器在DataGridView中显示WCF中的大量记录

时间:2013-01-04 10:24:01

标签: c# winforms wcf entity-framework pagination

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

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

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

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

理论上这一切都很好,但真正的使用场景让我暂时不再实施它了。例如,当我打开一个Datagridview对话框,需要显示一个相对较大的记录列表(大约20.000)时,需要大约10秒才能显示。在Clarion中,它会立即发生。 Clarion中有一个名为“定位器”的功能,它允许您通过键入记录属性(例如名称)开头的字母来定位记录。

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

我创造的东西与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中?

2 个答案:

答案 0 :(得分:0)

当多个程序访问它们时,Clarion TPS文件不会被破坏,因为它们使用文件锁定协议。如果他们通过共享的文件访问使用机会锁定(oplocks),因为锁定/解锁的顺序可能会出现偏差,或者如果您有任何运行Microsoft Security Essentials的客户端(它有&#),这可能会搞砸34;功能&#34;混合锁定/解锁的顺序,不,它不会被修复),但是否则它可以正常工作&#34;好&#34;。

你的代码很慢的原因是因为它必须通过文件中的所有行来进行迭代,这很慢,因为它的所有磁盘I / O和Clarion都没有进行任何缓存。 / p>

要访问数据,您可以: 1)使用this tool将您的TPS文件转换为CVS,并将它们导入您的SQL数据库。这已经得到了回复here

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

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

答案 1 :(得分:-1)

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