UPDATE: I recently published a WintellectNow course (Getting Started with Breeze.js) that goes into more depth using Breeze in the context of an AngularJS app. Use code NSTIEGLITZ-13 for a free 2 week WintellectNow trial.
- Rich “LINQ like” Querying
- Change Tracking
- Entity Relationship Navigation
- Client Caching
- Offline Saving
- Tight Integration with Web API and Entity Framework (neither are required)
- Access to any RESTful API using custom metadata
In future posts I will expand on the entire feature set. In this post, I’ll focus on the Rich “LINQ like” Querying.
LINQ like Querying
Advanced querying is probably the most compelling case for BreezeJS. If you’re familiar with Entity Framework, querying in BreezeJS will feel quite intuitive. With Breeze, you can easily write queries that filter, sort, page, project data, and even eager load relationships.
Here is a simple query that filters a list of customers by Company Name:
var query = breeze.EntityQuery.from('Customers') .where('CompanyName', FilterQueryOp.Contain, 'Around');
It is also possible to build up queries by chaining predicates. This is useful, for example, if you have a search page with many optional search parameters. In this example, I chain two predicates using and:
var query = breeze.EntityQuery.from('Customers'); var p1 = breeze.Predicate.create('ContactTitle', 'Contains', 'Rep'); var p2 = breeze.Predicate.create('City', 'Eq', 'London'); var pred = breeze.Predicate.and([p1, p2]); query = query.where(pred);
I’ve used the predicate technique before with Entity Framework on the service tier; I’m glad to see a similar technique on the client.
Just to show you what’s possible, below is an example of a pretty advanced query. It retrieves a list of all customers who have placed any orders with order details that have a quantity greater than 40:
var query = breeze.EntityQuery .from('Customers') .where('Orders', 'any', 'OrderDetails', 'all', 'Quantity', '>', 40);
As seem, it’s easy to filter deep into the object graph.
Now you have seen how to build a query, here is how you execute a query:
manager.executeQuery(query) .then(successCalllback) .fail(failCallback) .fin(finallyCallback); //execute the query and resolve to a promise
When you call executeQuery(query), Breeze will:
- Generate a URL which looks something like this:
- http://localhost:50283/breeze/Customer/Customers?$filter=Orders/any(x1: x1/OrderDetails/all(x2: x2/Quantity gt 40)
- Notice the where clause from the query has been converted into the URLs query string (a la ODATA).
- Asynchronously issues an HTTP GET to the server and expects a JSON payload in the returned HTTP response body
- Assuming the call was a success, Breeze reshapes the JSON data into Breeze entities and merges those entities into the local cache. It then resolve the promise, allowing you, the developer, to handle the returned data via the successCallback.
Thanks Breeze – that was awesome! Now in the successCallback I can bind the data to a view, log any errors in my failCallback, and do any cleanup in the fin callback.
Sorting in BreezeJS is super straight forward and pretty powerful. Check out this example from the BreezeJS documentation:
// Products sorted by their Category names, then by Product name (in descending order) var query = breeze.EntityQuery.from('Products') .orderBy('Category.CategoryName, ProductName desc');
The code is pretty self explanatory. It demonstrates that you can sort by related properties either ascending or descending. As an alternative to adding the desc text, there is also an orderByDesc method.
// Products in descending name order (version 2) var query = breeze.EntityQuery.from('Products') .orderByDesc('ProductName');
Breeze provides the ability to page data using the skip and take methods as demonstrated in this query:
// Get the 3rd page of 5 Customers // by skipping 10 Customers and taking the next 5 var query = breeze.EntityQuery.from('Customers') .orderBy('ContactName') .skip(10) .take(5);
If you don’t need all properties on an entity, you can use projection to retrieve only the relevant properties. For example, this query would allow you to wire up a view which lists a customer’s contact name and company name:
//We only need the company name and contact name var query = breeze.EntityQuery.from('Customers') .select('CompanyName, ContactName');
You can also project properties from related entities. For example, this query retrieves a list of customers who placed orders with freight charges over $500:
var query = breeze.EntityQuery.from('Orders') .where('Freight', FilterQueryOp.GreaterThan, 500) .select('Customer.CompanyName');
If you know you need related entities up front, it’s often a good idea to grab all of the data in a single call. Maybe you need to build a view which displays a list of customers in Mexico and their related orders. This query eagerly loads the customer’s orders:
var query = breeze.EntityQuery.from('Customers') .where('Country', 'eq', 'Mexico') .expand('Orders');
How easy is that?!
We focus on making sure your data is secure.
Together we review all your data sources and current storage capabilities.
This includes dealing with data in motion, data at rest and long-term archiving.
Put the right infrastructure in place.
Actively monitored 24x7x365
Together we carefully plan out all aspects of your data protection including archiving, backup, and how to recover it.
We take into consideration more than the physical storage and look at the entire solution including the network and encryption needs.
We make sure there are no surprises by actively tracking utilization and failures to keep your data and applications peforrming at their best.
More than technology
All Atmosera customers benefit from processes, policies, training and 24x7x367 technical resources.
Our customers have the peace of mind of knowing an industry expert has performed a thorough risk assessment,
identified a remediation plan and provided ongoing audit support to ensure customers stay protected.
Best of all, we understand this level of service is — and will continue to be — required year after year.
Disaster Recovery (DR)
Secure Delete for Azure Storage
Effectively backup and safeguard your data.
Safeguard your business and stay operational event when disasters strike.
Permanently delete all files and data stored on Azure
We always implement networks which deliverbetter security and usability.
All our deployments take into consideration the end-to-end solution andwe secure all aspects of the network and connectivity.
- Defense in Depth – Our approach offers a flexible and customizable set of capabilities based on enterprise-grade standards for performance, availability, and response.
- WANs, MANs, LANs, and VPNs – We provide comprehensive networking and high-speed connectivity options from Wide Area Networks (WAN), Metropolitan Area Networks (MAN) and Local Area Networks (LAN), as well as managed Virtual Private Networks (VPNs) and firewalls.
- Stay current – We can be counted on to deliver proactive testing and the most secure network protocols.
- Reduce vulnerabilities – We help your team leverage advanced security features coupled with relentless vigilance from trained experts.