C# 查询数据库与查询IQueryable以创建自动完成功能
我在我的wpf应用程序中有一个texbox控件,当用户输入时,我希望在其中获得一个自动完成的列表框。换句话说,我有一些类似谷歌搜索框的东西: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
我通过两种方式做到了这一点,我想知道哪一种更有效。 第一种方式: 当用户每次在文本框中输入文本时,我会通过查询数据库来更新列表框。因此,我有这样的想法:
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