Skip to content

Bound vs Unbound queries

malcolmgroves edited this page Sep 29, 2014 · 2 revisions

One concept worth understanding is the difference between a Bound and an Unbound Query.

An Unbound Query has not yet been assigned to a source of data. So the following string query:

Query.EndsWith('e')

is unbound, as we have not yet said what we're querying from. If you have a look at Code Completion for the EndsWith function above, it is returning an IUnboundStringQuery.

If we continue on and type a From function:

Query.EndsWith('e').From(Listbox1.Items)

we now have a Bound Query. Again, Code Completion will show you that we are getting back a IBoundStringQuery.

Why does this matter?

It is useful to be able to define a query, then later apply that to a source of data. For example, that's exactly what happens when you use the Predicate operation, like so:

Query.EndsWith('e').Predicate

This will return a TPredicate<String> that contains the Unbound Query logic. Later on, when this predicate is applied against a value, the query will be bound to the value and evaluated. It can then be bound again to another value and tested, as many times as desired.

Restrictions

Most query operations can be performed on both bound and unbound queries. You can see this with the following two queries, which are functionally identical:

Query.EndsWith('e').From(Listbox1.Items)
Query.From(Listbox1.Items).EndsWith('e')

In the first example, Query returns an Unbound Query, which contains an EndsWith operation. In the second example, Query.From returns a Bound Query, which also contains an identical EndsWith operation.

However, there are some operations which do not exist on both Bound and Unbound Queries, which hopefully make sense now you understand the concept.

For example, From can only be called on an Unbound Query, as it is From which does the binding. Again, you can test this out on the query below:

Query.From(Listbox1.Items).EndsWith('e').From(Listbox1.Items)

This won't compile, failing on the second call to From. The first call to From returns an IBoundStringQueryEnumerator, and this does not contain a From method.

Further, transformative functions like ToTStrings or ToTList, which return a new container of items from the query results, can only be invoked on a Bound Query. It would make no sense to try to create a new container of items from a query which has no data attached to it.