在我的微风查询中执行一个命令在我的情况下不起作用

时间:2013-06-01 11:36:07

标签: breeze

我在Durandal网络应用程序中使用breezejs。

这是我的代码,以获取我的发票和&背后的界限:

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")
        .orderBy('Lines.Number');

    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)
        .then(querySucceeded)
        .fail(queryFailed);

    function querySucceeded(data) {
        invoiceObservable(data.results[0]);
    }
};

以下是Invoice的模型:

public class Invoice
{
    [Key]
    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; }
}

请注意,对于每张发票,我有很多发票行:

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

以下是InvoiceLine的模型:

public class InvoiceLine
{
    [Key]
    public int Id { get; set; }
    [Required]
    public int Number { get; set; }
    [Required]
    public string Description { get; set; }
    public int InvoiceId { get; set; }

    public Invoice Invoice { get; set; }
}

问题:当我执行此微风查询时,我收到以下错误:

检索数据时出错。无法找到属性:类型上的行:发票

问题在于orderBy子句。我在Invoice和InvoiceLine之间有一对多的关系,因此在这种情况下我似乎无法执行订单。

我的问题:如何按号码对发票行进行排序?

感谢。

1 个答案:

答案 0 :(得分:3)

简短回答:你不能。这是实体框架的限制,而不是Breeze。

您无法在EF LINQ查询中使用“展开”过滤,选择或订购您包含的相关实体。

您可能会管理客户端上相关实体的排序顺序,例如订单行项目的显示。

另请注意,Breeze导航路径返回的实体集合是无序的。我不确定如果您尝试对Breeze实体导航集合(例如,Order.LineItems)进行排序会发生什么。我担心这会导致Breeze认为你对实体进行了更改......因为排序似乎会在排序时将实体移除并添加到集合中。事实上,你的EntityManager会认为有些变化尚未发生变化。

我尝试了一个实验,似乎一切正常。我在Northwind做了类似的事情:

  • 获取客户订单(“让我们停止N店”)

  • 检查了cust.Orders()的序列;他们有无序订单ID:[10719,10735,10884,10579]

  • 执行了这样一行:cust.Orders().sort(function(left, right){return left.OrderID() < right.OrderID()? -1 : 1})

  • 再次检查cust.Orders()的序列;这次他们排序:[10579,10719,10735,10884]

  • 检查了客户的EntityManager.hasChanges() ...仍然是假的(没有变化)。

我承认我很高兴。我需要编写一个适当的测试,以确保它可靠地工作。我必须确保Knockout绑定到导航属性以排序顺序显示它们。但到目前为止我受到了鼓励。

  

重要提示

     
      
  1. Breeze不会对列表进行排序。如果添加新订单或者由于后续查询,Breeze会向集合添加新订单,则必须执行此操作。

  2.   
  3. 您的排序会影响绑定到此导航属性的每个视图。如果您希望每个视图在该集合中拥有自己的实体类型,则必须维护单独的特定于视图的集合,这些集合会影响导航属性集合。

  4.   

如果我对所有这些都不对,那么你必须为每个ViewModel管理相关实体的影子集合,按照你的意愿排序。

6月2日更新

我怀疑我们必须通过调用valueHasMutated让KO了解排序后的数组更改。我花了15分钟进行实验。它似乎工作正常。

我从ASP.NET SPA模板创建了一个新的KO Todo应用程序(目前有关于缺少jQuery.UI库的虚假投诉,无论如何都是完全不必要的。)

我在delete-TodoList链接上方的 index.cshtml 添加了“排序链接”:

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

然后我在 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
}

像魅力一样工作。随意排序,添加,删除待办事项。当我添加和删除时,应用程序会在预期时保存...但在保存期间不会保存。

尝试valueHasMutated