1

我在我的 Durandal Web 应用程序中使用了微风。

这是我的代码,用于获取我的发票和后面的行:

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]);
    }
};

这是发票的模型:

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 之间有一对多的关系,所以在这种情况下我似乎无法执行 order by。

我的问题:如何继续能够按编号对我的发票行进行排序?

谢谢。

4

1 回答 1

3

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

您无法筛选、选择或排序在 EF LINQ 查询中使用“扩展”包含的相关实体。

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

另请注意,Breeze 导航路径返回的实体集合是无序的。如果您尝试对 Breeze 实体导航集合(例如 Order.LineItems)进行排序,我不确定会发生什么。我担心这会导致 Breeze 认为您已经对实体进行了更改......因为排序似乎会在排序时将实体删除并添加到集合中。您EntityManager会认为有待更改,而实际上没有任何实质内容发生变化。

我尝试了一个实验,一切似乎都很好。我用 Northwind 做了这样的事情:

  • 获取客户的订单(“Let's Stop N Shop”)

  • 检查序列cust.Orders();他们有无序的 OrderID:[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. 您的排序会影响绑定到此导航属性的每个视图。如果您希望每个视图在该集合中都有自己的实体类型,则必须维护单独的、特定于视图的集合,这些集合会影响导航属性集合。

如果我对所有这些都错了,您将必须为每个 ViewModel 管理相关实体的影子集合,按您的意愿排序。

6 月 2 日更新

我怀疑我们必须通过调用来让 KO 知道排序后数组的变化valueHasMutated。我花了 15 分钟做一个实验。它似乎工作正常。

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

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

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

然后我在viewModel.js中实现了它:

var sortAscending = true;
变量视图模型 = {
    ...
    排序列表:排序列表,
    ...
};
...
函数排序列表(列表){
    list.todos().sort(function(left, right) {
        返回(排序升序?1:-1)*
            (left.title().toLowerCase() < right.title().toLowerCase() ? -1 : 1);
    });
    sortAscending = !sortAscending; // 反向排序方向
    list.todos.valueHasMutated(); // 让 KO 知道我们已经排序
}

奇迹般有效。随意排序、添加、删除待办事项。该应用程序在我添加和删除时按预期保存......但在保存期间没有。

试一试valueHasMutated

于 2013-06-02T00:22:14.860 回答