Abstracting reactive extensions for sql server compact and implementing an instant search

Tags: csharp, rx, system.reactive, sql-compact

So in the last Rx article I talked about instant search. This article, we're going to go quite a few steps further and search an sql-compact-4 database asychronously! Thats right!

But! Its going to be a little head churner with lambdas and what nots, because we're going to encapsulate retreiving the data in a nice clean way(in my opinion)

You could also just:

What are we making:

enter image description here

You'll need the SQL CE Compact Toolbox because we are going to want an entity framework object context. (Which visual studio won't create for sqlce4 if its not a web project)

You'll also want the solution from the previous blog post on Rx.

Instructions:

Step 1 - Open the solution, open solution explorer (Ctrl + W, S). Right click the project and choose add new item. Select Data on the left and choose SQL Server Compact 4 Local Database (Phew!)

Step 2 - Its more easier to use Visual Studio's server explorer to create a new table. Open server explorer (Ctrl + W, L), it should show your database. (If it doesn't, right click connections and click add connection). Expand your database, Right click Tables and click Create Table.

Create a table like the following, note ID is an identity:

enter image description here

Step 3 - Throw in some data:

enter image description here

Step 4 - Add an entity model for your database. You'll need to have installed SQL Compact Toolbox, goto Tools>Sql Compact Toolbox, Right Click your database and click Add Entity Data Model to current project.

enter image description here

The code

We'll add two helper classes to abstract the task of searching our database asychronously with Rx.

So we're defining a method here that will be based on a Type T, which will be our entity object and TContext which will be the DataContext. This complete generic interface will help you later on when you want to mock and/or use DI. (I typically use MEF.)

We then implement it like so:

Notice, we'll use the T at runtime so we can use this like a repository for any entity object.

Our one and only function GetAllAsObservables, uses the ToAsync method to convert the lambda passed as an argument, into a function which returns an IObservable. We then make a call to this function getall().

We wrote ToAsync(Database1Entities, IQueryable<T>) so getall is a function that takes an instance of Database1Entities and returns an IObservable<T> which we transform/project into IObservable<IList<T>>

Our MainForm code now looks like this:

Explaination :

First off, what we did last time was, we changed the Textbox.TextChanged event to an observable sequence and throttled it by 500 milliseconds. So, our code got called by the system every 500ms, we then executed DO every time this happened.

The original SearchList function does not search asynchronously, you could try and put Thread.Sleep(5000) inside and it will block the UI.

So now!! We execute an async call through our little helper class, to search our database.

Remember our GetAllAsObservables() expects a lamba that takes our data context and returns an IQueryable<T>, this means you can pretty much run any query against your context an long as it returns the right type. Also, this runs in the context of sql, not in memory.

We get in return an IObservable<IList<T>> getfn. We then use ObserveOn because we're going to touch UI from another thread. (This is equivalent to those Invoke() calls you made in your old async code). This time on subscribe you are returned a an IList<Customer>. The lambda you pass into Subscribe is executed when the search is done async!

So try and run the code! Type in some names! =D

I hope this was useful, I'll take this further and get into how to properly abstract data access with Rx by creating Observable repositories. I've used these quite sucessfully in a number of apps!

Any critique, good, bad, ugly is welcome!

Happy Coding

Comments powered by Disqus