Query Reuse in Visual Studio LightSwitch
One of the features available in Visual Studio LightSwitch is to model queries that can be reused in other queries that you model. This allows developers to write a potentially complex query once and be able to define other queries which reuse that logic. In V1 of LightSwitch, this query reuse is exposed through the concept of a query source.
All queries that you create have a source. The source of a query defines the set of entities on which the query will operate. By default, any new query that you create will have its source set to the entity set of the table for which you created the query. So if I create a query for my Products table, the source of the query will be the Products entity set. You can think of the entity set as being similar to a SELECT * FROM TABLE for the table. The entity set is always the root; it does not have a source. Developers have the ability to change a query’s source. The source of a query can be set to another query that has already been defined. (You can do this as long as both queries are returning the same entity type. You can’t, for example, define a query for customers and a query for products and define the source of the products query to be the customer query.) This effectively creates a query chain where the results of one query are fed to the next query where the results are further restricted.
To illustrate how this works, let’s start with a sample set of Product data to work with:
Name | Category | DiscontinuedDate | UnitsInStock |
Chai | Beverages | 10/10/2010 | 6 |
Chef Anton's Cajun Seasoning | Condiments | <NULL> | 54 |
Guarana Fantastica | Beverages | <NULL> | 62 |
I’ve defined a query named ProductsByCategory that returns the products of a given category:
This query will return the following data when “Beverages” is passed as the Category parameter:
Name | Category | DiscontinuedDate | UnitsInStock |
Chai | Beverages | 10/10/2010 | 6 |
Guarana Fantastica | Beverages | <NULL> | 62 |
Now this query can be reused for any other query which wants to retrieve data for a specific category but also wants to further refine the results. In this case, I’ll define a query named DiscontinuedProducts that returns all discontinued products for a given category.
Notice the red bounding box which I’ve added to indicate that this query’s source is set to the ProductsByCategory query. You’ll also notice that this query “inherits” the Category parameter from its source query. This allows the DiscontinuedProducts query to consume that parameter in its filter should it need to do so. The result of this query is the following:
Name | Category | DiscontinuedDate | UnitsInStock |
Chai | Beverages | 10/10/2010 | 6 |
It may be helpful to think of object inheritance in the context of query sources. In other words, the DiscontinuedProducts query inherits the logic of ProductsByCategory and extends that logic with its own.
It should be noted that any sorts that are defined for queries are only applicable for the query that is actually being executed. So if ProductsByCategory sorted its products by name in descending order and DiscontinuedProducts sorted its products by name in ascending order, then the results of the DiscontinuedProducts query will be in ascending order. In other words, the sorting defined within base queries are ignored.
Comments
- Anonymous
October 21, 2010
Matt, thanks for the write up. This feature is very important and saves so much time and redundancy. ..Ben