Working with Breeze Lookup Queries

One capability of Breeze that is often overlooked or not fully understood is executing queries that bring back multiple collections of data. These are often referred to as lookup queries because they are a perfect fit for going to the server one time to get back a collection of lists that can be used for populating “lookup lists” – lists of objects that you will use to populate drop down lists or other selection lists in various places in the application. These are often coded lists of allowable values for an enumerated property on some object you are going to be editing, and are usually fairly invariant over time. But you could also use this capability to retrieve multiple collections of interrelated objects in a single shot if you can not achieve the same result through a normal query execution with filtering and expansion.

To execute a lookup query, the server needs to expose an API operation that return a JSON payload with a root object containing each of the collections as a named property. If you were implementing this with an ASP.NET BreezeController, the controller method would look like this:

   1: [BreezeController]

   2: public class ZzaController : ApiController

   3: {

   4:     EFContextProvider<ZzaDbContext> _ContextProvider = new EFContextProvider<ZzaDbContext>();

   5:  

   6:     [HttpGet]

   7:     public string Metadata()

   8:     {

   9:         return _ContextProvider.Metadata();

  10:     }

  11:  

  12:     [HttpGet]

  13:     public object Lookups()

  14:     {

  15:         var orderStatuses = _ContextProvider.Context.OrderStatuses.ToList();

  16:         var productOptions = _ContextProvider.Context.ProductOptions.ToList();

  17:         var productSizes = _ContextProvider.Context.ProductSizes.ToList();

  18:         return new { orderStatuses, productOptions, productSizes };

  19:     }

  20:  

  21: }

 

The resulting wire level format will be a single JSON object at the root of the payload, containing one or more named array properties that contain the lists. For the server method above, addressed as /breeze/Zza/Lookups, the response body would look roughly like this:

{ $id=1, $type=…, orderStatuses = […], productOptions […], productSizes =[…] }

The individual items in the arrays would need to be entity types that are included in the client side metadata and that express their type with additional metadata properties on the returned JSON:

{ $id=2, $type=’Zza.Data.OrderStatus, Zza.Data’, Id = 1, Name=’Ordered’ }

If using the Breeze ASP.NET Web API support to implement BreezeControllers with EntityContextProviders, to get this extra type information associated with the entities you just need to expose a DbSet property from your DbContext for each of the entity types in the collections you return, but you do not need to have a separate query method for those types exposed from your Web API Controller.

   1: public class ZzaDbContext : DbContext

   2: {

   3:     public DbSet<ProductOption> ProductOptions { get; set; }

   4:     public DbSet<ProductSize> ProductSizes { get; set; }

   5:     public DbSet<OrderStatus> OrderStatuses { get; set; }

   6: }

 

To execute the lookup query, you do it like any other query execution with Breeze, you just use the name of your server API operation in specifying the query:

   1: var em = new breeze.EntityManager('breeze/Zza');

   2: var lookupsQuery = breeze.EntityQuery.from('Lookups');

   3: em.executeQuery(lookupsQuery).then(successHandler, errorHandler);

 

The important part to understand is what you will see in the successHandler arguments vs. what will be created in the EntityManager cache. When your successHandler gets called, like for other Breeze queries, the data object that gets passed to your handler will contain a results array just like it does for any other query, but the results will have the single object returned in it. That single item in the array will be the single root object that the server side returned. And that object, as expressed by the server will have the named properties containing each of the arrays returned by the server.

What sometimes trips people up is understanding how that relates to what gets created in the cache so that you can query for those collections in the cache later. The thing to realize is that the collection names produced in the cache have nothing to do with the names of the properties for the collections in the server payload. In the example payload I showed above, I could have named the properties foo, bar, and baz instead of orderStatuses, productOptions, and productSizes. And if I did that, those would still be the names of the properties containing the arrays when received in the client executeQuery successHandler.

But if the types of those entities were OrderStatus, ProductOption, and ProductSize, the names of the resulting collections in the EntityManager cache after the query completes would still be OrderStatuses, ProductOptions, and ProductSizes respectively. So if you were going to write code to retrieve those entities from the cache later, the collection name you would want to use when creating an EntityQuery to query the local cache with executeQueryLocally would be the plural of the entity type name, not the name of the property that contained the collection in the server payload.

Here is client JavaScript that demonstrates that the name of the array property in the successHandler is different from the collection created in the EntityManager cache for the Lookups controller showed earlier, if you changed the orderStatuses local variable name in the server Lookups method to foo:

   1: var em = new breeze.EntityManager('breeze/Zza');

   2: var lookupsQuery = breeze.EntityQuery.from('Lookups');

   3: em.executeQuery(lookupsQuery).then(successHandler, errorHandler);

   4:  

   5: function successHandler(data) {

   6:     var results = data.results[0];

   7:     if (results.foo != null)

   8:         console.log("results contain foo collection");

   9:     var cacheResults = em.executeQueryLocally(breeze.EntityQuery.from("OrderStatuses"));

  10:     if (cacheResults.length > 0)

  11:         console.log("cache contains 'OrderStatuses' collection");

  12: }

 

Notice that the data.results[0] object is the root object returned by the Lookups method, and that still has a foo property for the array of OrderStatus objects. But the collection that is created in the EntityManager cache that you can query for is not based on the names of those arrays in the payload object, they are based on the type of the entities contained in the arrays – in this example OrderStatus. So the resulting EntityManager collection is OrderStatuses.

Hopefully that helps clarify the differences between what you see in the query completion results and what gets put in the cache. If you have questions, ping me on Twitter @briannoyes.

Comments Off

Reusable Async Validation in WPF with Prism 4.2

I recently wrote a post on implementing a reusable validation base class for models and view models in WPF using Prism 4.2 on the Pluralsight blog. You can find the whole article here:

http://blog.pluralsight.com/async-validation-wpf-prism

Comments Off

VSLive! Chicago Sessions

Had a great week presenting at VSLive! Las Vegas last week and am already looking forward to presenting again at VSLive! Chicago next. You can register for that conference with this link http://bit.ly/CHSPK22_Reg. In Chicago I’ll be presenting the following:

Full day workshop: Data-Centric Single Page Apps with Angular, Breeze, and Web API

Build Data-Centric HTML5 Single Page Applications with Breeze

Build Maintainable Windows Store Apps with MVVM and Prism

Zero to Connected with Windows Azure Mobile Services

Hope to see you there!

Comments Off

Programmatic WPF Bindings and Chaining CollectionViewSource

In my Pluralsight course WPF Data Binding in Depth, I barely covered using bindings from code behind, mainly because where bindings really shine is in XAML. But there are occasions where you need to set a binding from code behind. I got a question on my course discussion about an example I showed where I show how to chain CollectionViewSources (CVSs) to get a Master-Details presentation of parent and child collections and how you could do that from code behind. So rather than answer there, I’ll do it here where it is a little easier to show code and explanation.

First off, to chain the CVSs, you set them up as Resources like so:

<Window.Resources>

    <CollectionViewSource x:Key="customerViewSource" />

    <CollectionViewSource x:Key="customerOrdersViewSource" 

       Source="{Binding Orders, Source={StaticResource customerViewSource}}"/>

    <CollectionViewSource x:Key="customerOrdersOrderItemsViewSource" 

       Source="{Binding OrderItems, Source={StaticResource customerOrdersViewSource}}"/>

</Window.Resources>

In my course, I show how you can get all this done through simple drag and drop using the Data Sources Window. Here I will just focus on the code.

In this case, I am chaining two levels deep, from a Customers collection, to the Orders for each Customer, to the OrderItems for each Order. You can see that the key is to set the Source property of the child CVS to the parent CVS through a binding.

Then naturally there are UI elements, typically DataGrids, whose ItemsSource property gets bound to each CVS to present that level in the hierarchy:

<DataGrid x:Name="ordersDataGrid" 

ItemsSource="{Binding Source={StaticResource customerOrdersViewSource}}" ...>

 

So how would you do this from code behind? First you need to create the CVS instances:

private CollectionViewSource _customerViewSource = new CollectionViewSource();

private CollectionViewSource _customerOrdersViewSource 

  = new CollectionViewSource();

private CollectionViewSource _customerOrdersOrderItemsViewSource 

  = new CollectionViewSource();

 

Then you need to create the bindings for the child (and grandchild) CVS in code in the constructor or Loaded event:

var ordersBinding = new Binding("Orders");

ordersBinding.Source = _customerViewSource;

BindingOperations.SetBinding(_customerOrdersViewSource, 

    CollectionViewSource.SourceProperty, ordersBinding);

 

var orderItemsBinding = new Binding("OrderItems");

orderItemsBinding.Source = _customerOrdersViewSource;

BindingOperations.SetBinding(_customerOrdersOrderItemsViewSource, 

    CollectionViewSource.SourceProperty, orderItemsBinding);

 

FrameworkElement derived types have their own SetBinding method on them. For normal DependencyObjects like a CVS, you use the BindingOperations class to set a binding programmatically, passing it the object you want to set the binding on, the dependency property that will be the target on that object, and the binding you want to set it to.

Finally, since the XAML won’t have access to those CVSs (unless you expose them through a property you can bind to), you can set the bindings for the DataGrids in the code behind as well.

ordersDataGrid.SetBinding(DataGrid.ItemsSourceProperty, 

    new Binding { Source = _customerOrdersViewSource });

orderItemsDataGrid.SetBinding(DataGrid.ItemsSourceProperty, 

    new Binding { Source = _customerOrdersOrderItemsViewSource });

Then you need to set the root collection on the root CVS Source property (after loading the data from somewhere naturally).

_customerViewSource.Source = Customers;

Then you are off and running.

Again, I rarely set bindings programmatically like this. Most of the time it is better to keep your bindings in the XAML. But if you need to, there you go.

You can download a full sample here.

Comments Off

Passing Complex Query Parameters with Breeze

In my course Building Data-Centric Single Page Applications with Breeze, I cover Breeze’s ability to pass parameters when you execute a query. The basics of that are that there is a withParameters method on the EntityQuery object that lets you pass in a JavaScript object with key/value pair properties that will be turned into a query string parameter by breeze and passed along to the service. You need to make sure the resource you are querying has a corresponding method on the target controller that takes those parameters.

So lets say I executed a query on the client side like this:

var em = new breeze.EntityManager("breeze/Zza");

var queryWithParams = breeze.EntityQuery

    .from("ProductsWithSimpleParams")

    .withParameters({ name: "foo", description: "bar"});

em.executeQuery(queryWithParams, function (data) { products(data.results); });

Based on the set up of the EntityManager, I am targeting a BreezeController called ZzaController. Whatever I pass to the .from call is interpreted as the Resource that I want to query. Breeze will append that to the URL path requested, and based on the default action-based routing of Breeze, that means I will need to have a method called ProductsWithSimpleParams that responds to HTTP GET requests on my controller. Because I used the .withParameters call, passing a JavaScript object literal with properties name and description on it, Breeze will add these as query string parameters with their values on the request. When I execute the query, I get an HTTP GET request with a URL of:

GET /breeze/Zza/ProductsWithSimpleParams?name=foo&description=bar

To handle this call, I will need a method on the controller that looks like this:

[HttpGet]

public IQueryable<Product> ProductsWithSimpleParams(string name, string description)

{

    // Do something with params...

    return _ContextProvider.Context.Products;

}

A combination of the action-based routing of Breeze and the model binding system of ASP.NET Web API kicks in here and the method is selected by name based on the URL, and the parameters are matched against the query string parameters by name and case, so the call gets dispatched into this method with the parameters populated. Couldn’t be simpler.

However, what might not be so obvious is what if you need to pass more complex parameters to your queries from the client side, including complex types and/or collections of parameters.

Lets take the case of complex types as discrete parameters first. Say that on the server side, you want to take in a single complex object as a parameter:

public class ComplexParam

{

    public string name { get; set; }

    public string description { get; set; }

}

 

[HttpGet]

public IQueryable<Product> ProductsWithSingleComplexParam(ComplexParam param)

{

    // Do something with params...

    return _ContextProvider.Context.Products;

}

With model binding in ASP.NET this won’t work by default for a query method because it expects complex types to be in the HTTP body, and a GET request can’t have a body. So what can we do? Well, we know Breeze is going to put parameters in the query string anyway, so we just need to tell ASP.NET model binding where to look. If we use a [FromUri] attribute on the parameter, it will look to what it finds in the query string to try to come up with a ComplexParam object to pass in:

public IQueryable<Product> ProductsWithSingleComplexParam([FromUri] ComplexParam param)

Basically once you do that, ASP.NET will create a new ComplexParam object and try to populate any of its properties from query string parameters. So the same client side code that we were using before (other than the resource name changing to “ProductsWithSingleComplexParam”) that put name and description in the query string will now be use to populate the name and description properties of the ComplexParam object instead.

Note that there is case sensitive matching going on here, so that is why I non-conventionally defined my property names camelCase instead of the norm in .NET of PascalCased. You can work around this by using the Breeze camelCase convention to get that conversion to happen automatically on the client side, or you can use the JSON.NET convention conversion to do it on the server side. That is a separate subject, so I will just make sure my client and server are using the same casing for the samples I show here.

What if you want a signature that has multiple complex types in it, such as:

[HttpGet]

public IQueryable<Product> ProductsWithTwoComplexParams([FromUri] ComplexParam param1,

    [FromUri] ComplexParam2 param2)

{

    // Do something with params...

    return _ContextProvider.Context.Products;

}

where ComplexParam2 looks like:

public class ComplexParam2

{

    public int Age { get; set; }

    public string Comments { get; set; }

}

In this case if we change our query on the client side to this:

var queryWithTwoComplexParams = breeze.EntityQuery

    .from("ProductsWithTwoComplexParams")

    .withParameters({ name: "foo", description: "bar", age: 42, comments: "hello" });

em.executeQuery(queryWithTwoComplexParams, function (data) { products(data.results); });

Now model binding will create the two separate objects, ComplexParam and ComplexParam2 and will pull values for their properties out of the individual query string values from the client side.

What if you want to treat them as separate objects on the client side as well, to keep more of a 1:1 object model? Breeze withParameters still wants a single root JavaScript object to be passed to it, but that object can have nested objects. if our parameters on the server side are named param1 and param2 as shown above, then we just need to make sure the structure of the root object we pass matches that parameter naming:

var queryWithTwoComplexParamsAsObjects = breeze.EntityQuery

    .from("ProductsWithTwoComplexParams")

    .withParameters({ param1: { name: "foo", description: "bar" }, param2: { age: 42, comments: "hello" } });

em.executeQuery(queryWithTwoComplexParamsAsObjects, function (data) { products(data.results); });

Here I am hard coding the objects for demonstration purposes, but those param1 and param2 objects could be variables that point to an object that was originally returned from a query that brought back ComplexParam and ComplexParam2 objects.

Finally, what if you want to be able to pass a collection of objects as parameters to the server side? Well, again you are constrained by the fact that Breeze wants a single root object that you pass to withParameters, but that object can certainly contain a property that is an array of objects. To understand what to do here, we just need to drop back to the fundamentals of what is going to happen on each end of the wire. Breeze withParameters is going to take the JavaScript object you pass it and turn it into a JSON representation and put it into the query string with each root property of the JavaScript object as a separate parameter. On the server side, you need to use the [FromUri] to get that complex object representation deserialized into a server object that you can use in your service method.

So say we had a structure to the collection (array) of JavaScript complex objects that we wanted to pass like this:

var params = [{ propName: "Name", value: "foo" }, { propName: "Description", value: "bar" }];

var queryWithCollectionOfParams = breeze.EntityQuery.from("ProductsWithCollectionOfParams").withParameters({ values: params });

em.executeQuery(queryWithCollectionOfParams, function (data) { products(data.results); });

What ends up on the wire is a GET request like this:

GET /breeze/Zza/ProductsWithCollectionOfParams?values%5B0%5D%5BpropName%5D=Name&values%5B0%5D%5Bvalue%5D=foo&values%5B1%5D%5BpropName%5D=Description&values%5B1%5D%5Bvalue%5D=bar

Now that is a little hard to read with the URL encoding, so lets look at the decoded query string:

values[0][propName]=Name&values[0][value]=foo&values[1][propName]=Description&values[1][value]=bar

We can see that because we passed a root object with with a property named “values” that points to the array of JavaScript objects, Breeze broke that down and turned each array entry and each property for each entry into its own query string parameter. So what do we need to have that read back in to some strongly typed objects on the server side? First we need a model object corresponding to each entry object:

public class CollectionItem

{

    public string propName { get; set; }

    public string value { get; set; }

}

Then we need an array argument named values for our service method of those CollectionItems:

[HttpGet]

public IQueryable<Product> ProductsWithCollectionOfParams([FromUri] CollectionItem[] values)

{

    // Do something with params....

    return _ContextProvider.Context.Products;

}

Now we are good to go even with passing a collection of complex objects to the server side.

If you need to go beyond that, my first instinct is to recognize that not every service call from your JavaScript client that happens to be using Breeze MUST use Breeze for every data related call. Ultimately your BreezeController is a Web API controller with an action-based route. You can call any method in your controller (or any other controller for that matter) with simple AJAX calls through JQuery. So if you have highly complex parameter passing and return type requirements that Breeze seems to be getting in the way of accomplishing, just get it out of the way and make those calls as normal AJAX calls yourself.

Also be aware the Breeze Labs has a sample of how you can take control of POST requests to put whatever you want in the request body here: https://github.com/IdeaBlade/Breeze/tree/master/Breeze.Client/Scripts/Labs.

Hope you find this helpful for understanding some of the options in passing more than simple parameters to a query method through Breeze.

You can download the full sample here.

Comments Off

Yet Another Podcast – Breeze Roundtable

Want to get to know more about Breeze and where it fits into HTML client and Single Page Application development? This discussion that we had as a round table podcast discussion on Jesse Liberty’s Yet Another Podcast is a great place to start:

http://jesseliberty.com/2014/02/10/yet-another-podcast-120-breeze-roundtable/

Comments Off

Speaking at Microsoft Maniacs 18 March 2014

I’m going to give a talk at a new user group in Sterling Virginia on March 18: Designing RESTful Services with ASP.NET Web API. You can find all the details and sign up to attend here:

http://www.meetup.com/Microsoft-Maniacs/events/166143782/

Hope to see you there, come out and support this new group at their inaugural meeting!

Comments Off

Hello World Podcast with Shawn Wildermuth

Shawn recently started a new podcast called Hello World that is not your typical geek talk podcast. This one lets you get to know a little of the back story behind some of the authors, speakers, and trainers that you might have seen at conferences or heard talk on other podcasts.

So last week was my turn at bat.

I’ve got a pretty atypical history for a software guy in that I didn’t go right into computers from an early age. I was into surfing growing up in the San Diego area, then went off to the U.S. Naval Academy and had a successful first career as a Naval Officer and F-14 Radar Intercept Officer. So if you want to hear how the heck someone flying planes manages to switch careers to become a software architect who teaches other people deep topics on software technology, listen in!

http://wildermuth.com/hwpod/4_BrianNoyes

Comments Off

Use {x:Type} with WPF Implicit DataTemplates

I have burned myself with this little thing so many times, I’m long overdue for a simple blog post as a reminder to myself for the future.

When you use Implicit DataTemplates in WPF, you need to specify the DataType property using the {x:Type} markup extension. In Silverlight and later XAML technologies that support implicit DataTemplates this changed because there was no x:Type markup extension, you just specified the type like so.

        <DataTemplate DataType="local:ExplicitDataTemplatesViewModel">
            <local:ExplicitDataTemplatesView/>
        </DataTemplate>

But in WPF it needs to look like this:

        <DataTemplate DataType="{x:Type local:ExplicitDataTemplatesViewModel}">
            <local:ExplicitDataTemplatesView/>
        </DataTemplate>

Otherwise, the data templates won’t match up. Now that I have written this maybe I will never burn myself with this stupid little thing again….

Comments Off

Migrated dasBlog -> WordPress!

I’ve been wanting to get my blog moved over from dasBlog that I started using just over 10 years ago to WordPress for all the flexibility that WordPress offers – countless themes and plug ins, tools,etc. and now I am finally there. I want to thank the folks at hipinspire.com for the help in getting it done – they have been a fantastic resource us, both for this small little task and for getting our web site together at http://www.solliance.net.

Part of my inertia in not blogging lately has been feeling like I would just be adding more content that would have to be migrated. But mostly it has been the fact that I have been so damn busy with projects at Solliance, authoring Pluralsight courses, and speaking at conferences (always keep an eye over there ==>> for where and when).

But I am going to try to use this switch as a motivator to get into a more regular cadence of publishing more useful content here. We will see how that goes.