我遇到了一种情况,我想从数据库中获取数据,并将其分配给WPF中ListView控件中每行的工具提示。 (我正在使用C#4.0。)由于我之前没有做过这类事情,所以在我尝试在我的主WPF应用程序中使用它们之前,我已经开始使用更小,更简单的应用程序来解决这些问题。
我担心的一个问题是可能会降低的数据量。出于这个原因,我想我会使用LINQ to SQL,它使用延迟执行。我认为这将有助于而不是下拉数据,直到用户将鼠标移过相关行。为此,我将使用一个单独的函数将值分配给工具提示,从数据库中传递我需要传递给相关存储过程的参数。我正在使用LINQ to SQL进行2次查询,使用2个不同的存储过程,并将结果分配给2个不同的DataGrids。
尽管我知道LINQ to SQL确实使用了延迟执行,但我开始怀疑我写的一些代码是否会破坏我使用LINQ to SQL的整个意图。例如,在我更简单的应用程序中进行测试时,我选择了几个不同的值来查看它是如何工作的。一个值的选择没有带回任何数据,因为没有给定参数的数据。我认为这可能会导致用户混淆,所以我想我会检查我通过运行DBML相关方法(与存储过程相关)分配的列表的Count属性。考虑一下,我认为LINQ运行查询是必要的,以便为Count属性提供结果。我不正确吗?
如果我取消对列表的Count属性的调用,我仍然想知道我是否有问题;如果仍然可以调用LINQ,因为我通过函数调用将工具提示与控件相关联?
答案 0 :(得分:2)
您是正确的,当您调用Count属性时,它会迭代结果集。在你的上一个问题上不清楚,但LINQ可能会在你填充DataGrids时调用,在工具提示发挥作用之后。
编辑:但是,这并不意味着违约执行或使用它有任何问题,它会在最新的可能阶段执行,就在您需要数据时。如果您仍想在实际获取所有数据之前检查Count,则可以使用简单的LINQ to SQL函数来检查Any()行。 (实际上Any()可能比Count> 0)
更多答案 1 :(得分:1)
Alex是正确的,调用Count()或Any()将枚举LINQ表达式,导致查询执行。我建议重新考虑你的设计,因为你可能不希望每次用户移动他/她的鼠标时执行数据库查询。还存在查询数据库的延迟问题。在具有本地数据库的开发箱上可能是瞬时的,可能在负载很重的服务器上有多秒延迟。我建议创建一个DisplayTooltip()函数,该函数采用延迟计算的LINQ表达式。然后,您可以缓存结果或应用其他启发式方法来决定是否应该实际查询数据库。
答案 2 :(得分:1)
您应该使用Any()
,而不是Count()
,但即使Any()
也会导致查询被执行 - 毕竟,它无法确定是否有任何行结果集而不执行查询。但是正在执行查询,并且正在获取结果集。 Any()
将获取一行,Count()
将全部获取。
那就是说,我认为在鼠标悬停时发生非瞬时操作只是个坏主意。曾经有一个Outlook版本,当你翻过“打印”按钮时,它显示了一个有用的工具提示。不那么有用,它通过调用系统函数获取该工具提示的数据,该函数找出可用的打印机。所以你要找到一个菜单,按钮会抓住鼠标指针,UI会在它熄灭时冻结两秒钟,并想出如何显示你甚至没有要求的工具提示。我今天仍讨厌这个节目。不要成为这个人。
更好的方法是在填充屏幕上的可见数据后异步获取工具提示数据。创建一个BackgroundWorker
可以很容易地将数据提取到DataTable
,然后使DataTable
可用于RunWorkerCompleted
事件处理程序中的视图模型。 (这样做是为了不对UI线程上的UI绑定数据进行任何更新。)您可以在视图模型中实现一个ToolTip
属性,该属性返回一个默认值(可能为null,但也许是某些东西)如果“获取数据...”),如果包含工具提示数据的DataTable
为空,并且如果不是,则计算值。这应该是令人钦佩的。您甚至可以实现属性更改通知,以便在您获取数据时用户将鼠标指针悬停在其上时,工具提示仍会更新。