C# 在WinC窗体中使用实体框架制作SQL数据库表浏览器
我只是在寻找一些链接或一些一般方向的提示。我正在编写一个程序,用户可以访问sql server数据库中的许多不同表。例如,如果用户单击Foo按钮,它将打开一个gui对话框,其中显示Foo表的所有列。它的顶部还有一个文本框,用于过滤列中的数据。在大多数情况下,我所写的工作到目前为止至少还不错,但有时表现真的很慢,我忍不住觉得自己做错了什么。通常我的代码是这样的C# 在WinC窗体中使用实体框架制作SQL数据库表浏览器,c#,sql-server,winforms,performance,entity-framework,C#,Sql Server,Winforms,Performance,Entity Framework,我只是在寻找一些链接或一些一般方向的提示。我正在编写一个程序,用户可以访问sql server数据库中的许多不同表。例如,如果用户单击Foo按钮,它将打开一个gui对话框,其中显示Foo表的所有列。它的顶部还有一个文本框,用于过滤列中的数据。在大多数情况下,我所写的工作到目前为止至少还不错,但有时表现真的很慢,我忍不住觉得自己做错了什么。通常我的代码是这样的 //GUI Constructor will call a Load Function private void Load() {
//GUI Constructor will call a Load Function
private void Load()
{
//Context is a DbContext entity
var query = from q in context.Foo
select q;
datagrid.Datasource = query.ToList();
}
我觉得出错的部分是文本框过滤器搜索。我现在的做法是基本上重新查询数据库以获得更具体的行。在TextBox TextChanged事件中调用此函数。我知道这对调用每个按键都不好,我本来打算添加一个计时器,在应用过滤器之前等待用户停止键入,但无论如何,这就是代码
private void TextFilter()
{
var query = from q in context.Foo.Where( x => x.Name == FilterTextbox.Text )
select q;
datagrid.Datasource = query.ToList();
}
我认为最好将load函数中的整个数据库存储到一个列表中,这样所有信息都已经在程序内存中了,但这实际上比再次查询数据库要慢。我还尝试使用Context.Foo.Local并从中查询,但结果证明,它与将所有数据存储在我自己的列表中一样慢
private void AlternateLoad()
{
context.Foo.Load();
datagrid.Datasource = context.Foo.Local.ToList();
}
private void AlternateTextSearch()
{
var query = from q in context.Foo.Local.Where( x => x.Name == FilterTextBox.Text )
select q;
datagrid.Datasource = query.ToList();
}
在使用本地或我自己的列表时,我尝试过使用Asparell,但似乎没有什么不同。不管怎样,我只是想看看如何加快速度。在一个特定的场景中,我在显示数据之前对数据库进行了预筛选,预筛选程序花了大约19秒才能显示其7行结果。较小的表很好,但具有100k+行的表肯定揭示了代码的弱点。任何关于如何做到这一点的提示或一般链接都将不胜感激。我一直在到处找,没找到任何东西
非常感谢 对于应用程序来说,最好的解决方案是什么,这实际上取决于您自己,但以下应该是一些可靠的建议,以便继续: 不返回您不需要的数据:前100行/分页 LINQ查询==>.First.Skip.Take 内存过滤也可以非常快!将整个列表保留在内存中,并对此集合运行linq查询 使用要筛选的参数创建StoredProcess,并
在可能要筛选的列上放置索引。我建议在classa列表中添加一个私有成员变量:
public MyClass
{
private List<Foo> myFoo = new List<Foo>();
//GUI Constructor will call a Load Function
private void Load()
{
//Context is a DbContext entity
var query = from q in context.Foo
select q;
// set the private member variable "myFoo" here
datagrid.Datasource = myFoo = query.ToList();
}
private void TextFilter()
{
// don't requery the DB, query the list myFoo
//var query = from q in context.Foo.Where( x => x.Name == FilterTextbox.Text )
//select q;
var query = myFoo.Where(x => x.Column == SearchCriteria).ToList();
datagrid.Datasource = query;
}
}
注意:上面的代码没有经过测试,希望能为您指明正确的方向
同样重要的是:由于您没有重新查询数据库,列表中的数据可能会过时。对于数据库浏览器之类的东西,我认为EF不适合。如果您有一个已定义的静态数据库模型,EF工作得最好,但是数据库浏览器应该能够动态地发现新表、新表的列以及其中存储的数据。我建议只使用原始的ADO.NET SqlConnection,SqlCommand作为数据库浏览器。嗯,我想我不是指整个数据库浏览器,而是指表浏览器/选择列表。这只是用户查看表记录并在需要时在另一个专用GUI中编辑它们的一种方式@marc_sHmm,我完全忘记了,我必须调查一下,我会让你知道结果的!谢谢所以仔细想想,当你处理超过100k行时,没有一个用户真的会在这么多行中搜索。我决定同意你的想法,只显示前100名的结果。现在只需使用Take100,它的运行速度就非常快。非常感谢,先生!我已经试着保留自己的列表来保存数据,因为某些原因,它比查询数据库运行得慢。不知道为什么。谢谢你!