我正在尝试在一个拥有10000多条记录的数据库表上实现即时搜索。
当搜索文本框内的文本发生变化时,搜索就会开始。当搜索框变为空时,我想调用另一个方法来加载所有数据。
此外,如果用户在加载另一个搜索结果时更改了搜索字符串,则应停止加载那些结果,并转而使用新搜索。
我已经按照以下代码进行了实现,但我想知道是否有更好或更清晰的方法来使用 Rx(响应式扩展)运算符来完成此项工作。我觉得在第一个可观察对象的订阅方法中创建第二个可观察对象比较命令式,对于那个if语句也是一样。
var searchStream = Observable.FromEventPattern(s => txtSearch.TextChanged += s, s => txtSearch.TextChanged -= s)
.Throttle(TimeSpan.FromMilliseconds(300))
.Select(evt =>
{
var txtbox = evt.Sender as TextBox;
return txtbox.Text;
}
);
searchStream
.DistinctUntilChanged()
.ObserveOn(SynchronizationContext.Current)
.Subscribe(searchTerm =>
{
this.parties.Clear();
this.partyBindingSource.ResetBindings(false);
long partyCount;
var foundParties = string.IsNullOrEmpty(searchTerm) ? partyRepository.GetAll(out partyCount) : partyRepository.SearchByNameAndNotes(searchTerm);
foundParties
.ToObservable(Scheduler.Default)
.TakeUntil(searchStream)
.Buffer(500)
.ObserveOn(SynchronizationContext.Current)
.Subscribe(searchResults =>
{
this.parties.AddRange(searchResults);
this.partyBindingSource.ResetBindings(false);
}
, innerEx =>
{
}
, () => { }
);
}
, ex =>
{
}
, () =>
{
}
);
SearchByNameAndNotes
方法只是通过从数据读取器中读取数据,在 SQLite 中返回一个 IEnumerable<Party>
。
SelectMany
子句是另一次尝试的一部分。它在我的原始代码中有注释,问题的最终版本没有错误(希望如此)。 - Ibrahim Najjar