C# 在WinC窗体中使用实体框架制作SQL数据库表浏览器

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() {

我只是在寻找一些链接或一些一般方向的提示。我正在编写一个程序,用户可以访问sql server数据库中的许多不同表。例如,如果用户单击Foo按钮,它将打开一个gui对话框,其中显示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;

    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,它的运行速度就非常快。非常感谢,先生!我已经试着保留自己的列表来保存数据,因为某些原因,它比查询数据库运行得慢。不知道为什么。谢谢你!