我有这个基于 Clarion TPS 的商业软件,我想用我用 C# 编写的软件替换它,使用以下技术:
- SQL Server 2008 R2 速成版
- 实体框架 4
- 具有 wsHttpBinding 和使用 UserNamePassword 凭据的基于消息的安全性的 WCF 服务
- 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 中?