Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 查询数据库与查询IQueryable以创建自动完成功能_C#_Database_Performance_Linq_Iqueryable_System.reactive - Fatal编程技术网

C# 查询数据库与查询IQueryable以创建自动完成功能

C# 查询数据库与查询IQueryable以创建自动完成功能,c#,database,performance,linq,iqueryable,system.reactive,C#,Database,Performance,Linq,Iqueryable,System.reactive,我在我的wpf应用程序中有一个texbox控件,当用户输入时,我希望在其中获得一个自动完成的列表框。换句话说,我有一些类似谷歌搜索框的东西: 我通过两种方式做到了这一点,我想知道哪一种更有效。 第一种方式: 当用户每次在文本框中输入文本时,我会通过查询数据库来更新列表框。因此,我有这样的想法: void textBox1_KeyUp(object sender, KeyEventArgs e) { // new text var content = ((Tex

我在我的wpf应用程序中有一个texbox控件,当用户输入时,我希望在其中获得一个自动完成的列表框。换句话说,我有一些类似谷歌搜索框的东西:


我通过两种方式做到了这一点,我想知道哪一种更有效。

第一种方式: 当用户每次在文本框中输入文本时,我会通过查询数据库来更新列表框。因此,我有这样的想法:

void textBox1_KeyUp(object sender, KeyEventArgs e)
{
        // new text
        var content = ((TextBox)sender).Text;

        // I am selecting the posible items using ado.net
        var posibleItems= PdvEntities.Entities.TableFoos.Where(TableFoo=> TableFoo.Description.Contains(content)).Select(c=>c);


        listbox1.ItemsSource = posibleItems;
}
注意,使用这种方法,每次在该文本框上触发keyup事件时,我都会查询数据库

第二种方式: 我执行以下操作,而不是每次激发keyup事件时都查询数据库:

// select all items and store that as a global variable
IQueryable allItems = PdvEntities.Entities.TableFoos.Select(a => a);


void textBox1_KeyUp(object sender, KeyEventArgs e)
{
        // new text
        var content = ((TextBox)sender).Text;

        // I don't have the code but I will then filter variable 
        // allItems based if their description contains 'content'

        // pseudo code
        newFileter <- filter of allItems that contain content


        listbox1.ItemsSource = newFileter;
}
//选择所有项目并将其存储为全局变量
IQueryable allItems=pdventies.Entities.TableFoos.Select(a=>a);
void textBox1\u KeyUp(对象发送方,KeyEventArgs e)
{
//新文本
var content=((文本框)sender.Text;
//我没有代码,但我会过滤变量
//allItems基于其描述是否包含“内容”
//伪码

newFileter如果您的
pdventies
类是EntityFramework上下文,那么下面是一个Linq to Entities查询,它将根据您的数据库生成T-SQL,并仅获取筛选的项

var posibleItems= PdvEntities.Entities.TableFoos
  .Where(TableFoo=> TableFoo.Description.Contains(content)).Select(c=>c);
不确定我是否理解您的其他解决方案。正如@svik提到的,您可以使用
ToArray()
ToList()
来获取内存中的所有项,但这根本不会起作用

看起来您需要限制对数据库的调用,以便根据使用类型,每隔
n
秒发送一个带有过滤器的查询

看一看。它会让你以一种很好的方式控制你的按键事件

我在这里写了一篇文章:
(这只是限制搜索)

然后是另一个关于linq to entities以限制数据库搜索的例子:


根据我在文章中所写的内容,你可以这样做:

你需要一个小帮手

public class ObservableHelper<T>
    where T : class //or EntityObject 
{
    public ObservableHelper()
    {
        _dat = new PdvEntities();
    }
    PdvEntities _dat;
    public IObservable<IList<T>> GetAllAsObservables
                                (Func<PdvEntities, IQueryable<T>> funcquery)
    {
        var getall = Observable.ToAsync<PdvEntities, IQueryable<T>>(funcquery);
        return getall(_dat).Select(x => x.ToList());
    }
}
公共类可观察帮助器
其中T:class//或EntityObject
{
公共可观察帮助者()
{
_dat=新的PDventies();
}
通风量;
公共IObservable GetAllasobervable
(Func funcquery)
{
var getall=Observable.ToAsync(funcquery);
返回getall(_dat).Select(x=>x.ToList());
}
}
然后以您的形式:

public Form1()
{
    InitializeComponent();
    //your playing with IQueryable<TableFoos>
    _repo = new ObservableHelper<TableFoos>()

    Observable.FromEventPattern(h => textBox1.KeyUp += h,
                           h => textBox1.KeyUp -= h)//tell Rx about our event
        .Throttle(TimeSpan.FromMilliseconds(500), cs)///throttle
        .ObserveOn(Scheduler.Dispatcher);//so we have no cross threading issues
        .Do(a => SearchList(textBox1.Text))//do this method 
        .Subscribe();
}

IObservableHelper<TableFoos, PdvEntities> _repo;

void SearchList(string query)
{//AS MANY keystrokes are there, this function will be called only
 // once every 500 milliseconds..

    listBox1.Items.Clear();
    listBox1.BeginUpdate();
    var getfn = _repo.GetAllAsObservables
        (d => d.TableFoos.Where(c => c.TableFoos.Contains(query)));
    getfn.ObserveOn(this).Subscribe(resultList => //is an IList<TableFoos>
        {
            foreach (var item in resultList)
            {
                listBox1.Items.Add(...
            }
            listBox1.EndUpdate();
        });
}
public Form1()
{
初始化组件();
//你在玩IQueryable
_repo=新的可观察帮助者()
可观察的。FromEventPattern(h=>textBox1.KeyUp+=h,
h=>textBox1.KeyUp-=h)//告诉Rx我们的事件
.Throttle(时间跨度从毫秒(500),cs)///Throttle
.ObserveOn(Scheduler.Dispatcher);//因此我们没有跨线程问题
.Do(a=>SearchList(textBox1.Text))//执行此方法
.Subscribe();
}
IObservableHelper\u repo;
无效搜索列表(字符串查询)
{//由于有许多击键,因此仅调用此函数
//每500毫秒一次。。
listBox1.Items.Clear();
listBox1.BeginUpdate();
var getfn=\u repo.GetAllAsObservables
(d=>d.TableFoos.Where(c=>c.TableFoos.Contains(query));
getfn.ObserveOn(this.Subscribe)(resultList=>//是一个IList
{
foreach(结果列表中的变量项)
{
listBox1.Items.Add(。。。
}
listBox1.EndUpdate();
});
}

如果您的
pdventies
类是EntityFramework上下文,那么下面是一个Linq to Entities查询,它将根据您的数据库生成T-SQL,并仅获取筛选的项

var posibleItems= PdvEntities.Entities.TableFoos
  .Where(TableFoo=> TableFoo.Description.Contains(content)).Select(c=>c);
不确定我是否理解您的其他解决方案。正如@svik提到的,您可以使用
ToArray()
ToList()
来获取内存中的所有项,但这根本不会起作用

看起来您需要限制对数据库的调用,以便根据使用类型,每隔
n
秒发送一个带有过滤器的查询

看一看。它会让你以一种很好的方式控制你的按键事件

我在这里写了一篇文章:
(这只是限制搜索)

然后是另一个关于linq to entities以限制数据库搜索的例子:


根据我在文章中所写的内容,你可以这样做:

你需要一个小帮手

public class ObservableHelper<T>
    where T : class //or EntityObject 
{
    public ObservableHelper()
    {
        _dat = new PdvEntities();
    }
    PdvEntities _dat;
    public IObservable<IList<T>> GetAllAsObservables
                                (Func<PdvEntities, IQueryable<T>> funcquery)
    {
        var getall = Observable.ToAsync<PdvEntities, IQueryable<T>>(funcquery);
        return getall(_dat).Select(x => x.ToList());
    }
}
公共类可观察帮助器
其中T:class//或EntityObject
{
公共可观察帮助者()
{
_dat=新的PDventies();
}
通风量;
公共IObservable GetAllasobervable
(Func funcquery)
{
var getall=Observable.ToAsync(funcquery);
返回getall(_dat).Select(x=>x.ToList());
}
}
然后以您的形式:

public Form1()
{
    InitializeComponent();
    //your playing with IQueryable<TableFoos>
    _repo = new ObservableHelper<TableFoos>()

    Observable.FromEventPattern(h => textBox1.KeyUp += h,
                           h => textBox1.KeyUp -= h)//tell Rx about our event
        .Throttle(TimeSpan.FromMilliseconds(500), cs)///throttle
        .ObserveOn(Scheduler.Dispatcher);//so we have no cross threading issues
        .Do(a => SearchList(textBox1.Text))//do this method 
        .Subscribe();
}

IObservableHelper<TableFoos, PdvEntities> _repo;

void SearchList(string query)
{//AS MANY keystrokes are there, this function will be called only
 // once every 500 milliseconds..

    listBox1.Items.Clear();
    listBox1.BeginUpdate();
    var getfn = _repo.GetAllAsObservables
        (d => d.TableFoos.Where(c => c.TableFoos.Contains(query)));
    getfn.ObserveOn(this).Subscribe(resultList => //is an IList<TableFoos>
        {
            foreach (var item in resultList)
            {
                listBox1.Items.Add(...
            }
            listBox1.EndUpdate();
        });
}
public Form1()
{
初始化组件();
//你在玩IQueryable
_repo=新的可观察帮助者()
可观察的。FromEventPattern(h=>textBox1.KeyUp+=h,
h=>textBox1.KeyUp-=h)//告诉Rx我们的事件
.Throttle(时间跨度从毫秒(500),cs)///Throttle
.ObserveOn(Scheduler.Dispatcher);//因此我们没有跨线程问题
.Do(a=>SearchList(textBox1.Text))//执行此方法
.Subscribe();
}
IObservableHelper\u repo;
无效搜索列表(字符串查询)
{//由于有许多击键,因此仅调用此函数
//每500毫秒一次。。
listBox1.Items.Clear();
listBox1.BeginUpdate();
var getfn=\u repo.GetAllAsObservables
(d=>d.TableFoos.Where(c=>c.TableFoos.Contains(query));
getfn.ObserveOn(this.Subscribe)(resultList=>//是一个IList
{
foreach(结果列表中的变量项)
{
列表B