Take the 2-minute tour ×

I use breezejs in my Durandal web application.

Here is my code to get my invoice & lines behind it:

var getInvoiceById = function (invoiceId, invoiceObservable, forceRemote) {
    // Input: invoiceId: the id of the invoice to retrieve
    // Input: forceRemote: boolean to force the fetch from server
    // Output: invoiceObservable: an observable filled with the invoice

    if (forceRemote)
        queryCacheInvoice = {};

    var query = entityQuery.from('Invoices')
        .where('id', '==', invoiceId)
        .expand("Client, Client.Contacts, Lines")

    var isInCache = queryCacheInvoice[invoiceId];

    if (isInCache && !forceRemote) {
        query = query.using(breeze.FetchStrategy.FromLocalCache);
    } else {
        queryCacheInvoice[invoiceId] = true;
        query = query.using(breeze.FetchStrategy.FromServer);

    return manager.executeQuery(query)

    function querySucceeded(data) {

And here is the models for Invoice:

public class Invoice
    public int Id { get; set; }
    public string Number { get; set; }
    public DateTime? Date { get; set; }
    public int? ClientId { get; set; }
    public string Comment { get; set; }
    public double? TotalExclVAT { get; set; }        
    public double? TotalInclVAT { get; set; }
    public double? TotalVAT { get; set; }
    public bool? WithoutVAT { get; set; }

    public virtual List<InvoiceLine> Lines { get; set; }
    public virtual Client Client { get; set; }

Please notice that for each invoice I have many invoice lines:


And here is the models for InvoiceLine:

public class InvoiceLine
    public int Id { get; set; }
    public int Number { get; set; }
    public string Description { get; set; }
    public int InvoiceId { get; set; }

    public Invoice Invoice { get; set; }

The problem: when I execute this breeze query I got the error below:

Error retreiving data. unable to locate property: Lines on type: Invoice

The problem is around the orderBy clause. I have a 1-to-many relationship between the Invoice and the InvoiceLine so it seems I cannot perform an order by in this case.

My question: how to proceed to be able to sort my lines of invoice by number?


share|improve this question

1 Answer 1

up vote 1 down vote accepted

Short answer: You can't. This is a limitation of Entity Framework, not Breeze.

You cannot filter, select, or order the related entities that you include with "expand" in an EF LINQ query.

You will probably manage the sort order of related entities on the client, e.g., the display of your order line items.

Note also that the collection of entities returned by a Breeze navigation path is unordered. I wasn't sure what happens if you tried to sort a Breeze entity navigation collection (e.g., Order.LineItems). I was afraid that would cause Breeze to think that you had made changes to the entities ... because a sort would seem to remove-and-add entities to the collection as it sorted. Your EntityManager would think there were changes pending when, in fact, nothing of substance has changed.

I tried an experiment and it all seems to work fine. I did something like this with Northwind:

  • fetched the Orders of a Customer ("Let's Stop N Shop")

  • checked the sequence of cust.Orders(); they have unordered OrderIDs: [10719, 10735, 10884, 10579]

  • executed a line like this: cust.Orders().sort(function(left, right){return left.OrderID() < right.OrderID()? -1 : 1})

  • checked the sequence of cust.Orders() again; this time they are sorted: [10579, 10719, 10735, 10884]

  • checked the customer's EntityManager.hasChanges() ... still false (no changes).

I confess that I am happily surprised. I need to write a proper test to ensure that this works reliably. And I have to make sure that the Knockout binding to the navigation property displays them in the sorted order. But I'm encouraged so far.

Important Notes:

  1. Breeze won't keep the list sorted. You'll have to do that if you add new orders or if Breeze adds new orders to the collection as a result of subsequent queries.

  2. Your sort affects every view that is bound to this navigation property. If you want each view to have its own sort of the entities in that collection, you'll have to maintain separate, view-specific collections that shadow the navigation property collection.

If I am wrong about all of this, you'll have to manage a shadow collection of the related entities, sorted as you wish, for each ViewModel.

Update 2 June

I suspected that we would have to let KO know about the array change after sort by calling valueHasMutated. I took 15 minutes for an experiment. And it seems to work fine.

I created a new KO Todo app from the ASP.NET SPA template (there's currently a phantom complaint about a missing jQuery.UI library which is totally unnecessary anyway).

I added a "sort link" to the index.cshtml just above the delete-TodoList link:

<a href="#" data-bind="click: $parent.sortList">Sort</a>

Then I implemented it in viewModel.js:

var sortAscending = true;
var viewmodel = {
    sortList: sortList,
function sortList(list) {
    list.todos().sort(function(left, right) {
        return (sortAscending ? 1 : -1) *
            (left.title().toLowerCase() < right.title().toLowerCase() ? -1 : 1);
    sortAscending = !sortAscending; // reverse sort direction
    list.todos.valueHasMutated();   // let KO know that we've sorted

Works like a charm. Sorting, adding, deleting Todos at will. The app is saving when expected as I add and delete ... but not during save.

Give valueHasMutated a try.

share|improve this answer
I was not aware about the limitation of Entity Framework about that. I try as you suggested by performing a sort on the UI something like this cust.Orders().sort(function(left, right){return left.OrderID() < right.OrderID()? -1 : 1}). The sort is effectively performed that's a good poing BUT there is another problem that appeared: before I was able to add/remove elements of my nested entity and immediately having the UI reflected my action (showing/hiding the added/removed element). (continue on next comment)... –  Bronzato Jun 2 '13 at 7:57
... With the sort performed the UI is no more refreshed. For example, when deleting an element (invoice line) from my nested entity, my UI didn't remove the element from my foreach on my observableArray. By removing the sort (only 1 line of code) it is working again as before. Do you noticed that problem? Any idea to have the sort working on nested entity WITHOUT break functionalities? Thanks anyway! –  Bronzato Jun 2 '13 at 7:57
See my answer update. –  Ward Jun 2 '13 at 17:24
Thanks for your update. When I inject invoice.lines.valueHasMutated(); in my code on the line below my sort I got the error: Error retreiving data. Cannot call method 'valueHasMutated' of undefined. Then I proceed like that: if (invoice && invoice.lines) invoice.lines.valueHasMutated(); but I still has the problem explained in my previous comment. –  Bronzato Jun 2 '13 at 18:01
The error message tells you what you need to know: you do not have the data. You have a timing problem. No point in adding that "if" test; all it does is keep the valueHasMutated from executing; you have to call valueHasMutated to get KO to listen and update the UI. I cannot explain your experience without the actual code. I've told you how to create my sample - it should take you 15 minutes. I suggest that you start there and compare with your code to see what is different. Good luck –  Ward Jun 2 '13 at 22:10

Your Answer


