我正在开发一个在后端使用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 - 但这不是这里的目标。
感谢
答案 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);