如何使用BreezeJs中的组功能过滤记录

时间:2015-03-12 16:24:04

标签: entity-framework breeze single-page-application

我正在开发一个在后端使用breezejs和Entity Framework 6的客户端应用程序。我有这样的陈述:

        var country = 'Mexico';

        var customers = EntityQuery.from('customers')
            .where('country', '==', country) 
            .expand('order')

我想使用每个客户可能会有数百个订单。出于性能目的,我只想检索每个客户的最新订单。这将基于订单的创建日期。在SQL中,我可以这样写:

    SELECT c.customerId, companyName, ContactName, City, Country, max(o.OrderDate) as LatestOrder FROM Customers c
        inner join Orders o on c.CustomerID = o.CustomerID
        group by c.customerId, companyName, ContactName, City,  Country

如果这是针对northwind数据库运行的,则只为每个客户返回最近的订单行。

如何在breeze中编写类似的查询,以便它在服务器端运行,从而将更少的数据返回给客户端。我知道我可以在客户端上处理这一切,但是在一个可以由客户端运行的查询语法中编写一些javascript - 但这不是这里的目标。

感谢

1 个答案:

答案 0 :(得分:1)

对于这样的情况,您应该创建一个特殊的端点方法来执行您的查询 然后,您可以使用实体框架查询来执行所需的操作,使用LINQ语法。 以下是两个Web API示例:

[HttpGet]
public IQueryable<Object> CustomersLatestOrderEntities()
{
    // IQueryable<Object> containing Customer and Order entity
    var entities = ContextProvider.Context.Customers.Select(c => new { Customer = c, LatestOrder = c.Orders.OrderByDescending(o => o.OrderDate).FirstOrDefault() });
    return entities;
}

[HttpGet]
public IQueryable<Object> CustomersLatestOrderProjections()
{
    // IQueryable<Object> containing Customer and Order entity
    var entities = ContextProvider.Context.Customers.Select(c => new { Customer = c, LatestOrder = c.Orders.OrderByDescending(o => o.OrderDate).FirstOrDefault() });

    // IQueryable<Object> containing just data fields, no entities
    var projections = entities.Select(e => new { e.Customer.CustomerID, e.Customer.ContactName, e.LatestOrder.OrderDate });
    return projections;
}

请注意,您可以在此处选择。您可以返回实际实体,也可以只返回一些数据字段。哪种适合您取决于您​​将如何在客户端上使用它们。如果它们只是用于显示 不可编辑的列表,您只需返回普通数据(CustomersLatestOrderProjections以上)。如果他们可以 编辑,然后返回包含实体的对象(CustomersLatestOrderEntities)。 Breeze将合并实体 进入缓存,即使它们包含在这个匿名对象中。

无论哪种方式,因为它返回IQueryable,您可以使用客户端的Breeze过滤语法来进一步限定查询。

var projectionQuery = breeze.EntityQuery.from("CustomersLatestOrderProjections")
    .skip(20)
    .take(10);

var entityQuery = breeze.EntityQuery.from("CustomersLatestOrderEntities")
    .where('customer.countryName', 'startsWith', 'C');
    .take(10);