我在我的项目中使用 Angular、breeze、WebApi、EF、SqlServer2008。 我有表Articles和表ArticleComments,所以一篇文章可以有很多articleComments记录。
public class Article{
public int ArticleId { get; set; }
public string ArticleName { get; set; }
public string Description { get; set; }
public ICollection<ArticleComment> Comments { get; set; }
public ICollection<ArticleImage> ImagesList { get; set; }
...
}
public class ArticleComment
{
public int ArticleCommentId { get; set; }
public string CommentText { get; set; }
public int UserId { get; set; }
public int Rate { get; set; }
public DateTime CommentDate { get; set; }
public int ArticleId { get; set; }
public Article Article { get; set; }
public int Status { get; set; }
}
在客户端中,我需要获取包含评论、图像和其他链接实体的完整文章实体,但评论只需要针对选定的文章记录,并且字段“状态”== 1。
我尝试使用这样的查询
var pred = breeze.Predicate.create('articleId', 'eq', id)
.and('comments', 'any', 'status', '==', 1);
return EntityQuery.from("Articles")
.where(pred)
.expand('comments, imagesList...')
.toType(entityNames.article)
.using(manager).execute()
.to$q(querySucceded, self._queryFailed);
这将返回文章的所有评论,但不会按状态字段过滤扩展表 ArticleComments。
最佳答案
杰里米是对的。这是 EF 长期存在的痛点。事实上,OData 不支持过滤 expand
的方式,这并没有让情况变得更好。 .
您可以通过投影在服务器端做您想做的事情。我在 DocCode 示例中尝试了这个想法。
我添加了一个新的CustomersAnd1998Orders
方法 NorthwindRepository
它在 NorthwindController
上向客户端公开
这是一个完全可查询的端点。它返回客户以及他们在 1998 年订购的订单。奇怪的是,它返回类型为 CustomerDto
的 JSON。而不是Customer
。您必须根据客户端查询进行调整......正如我将在下面解释的那样。
I don't know why I have to do this. If I project into
Customer
, I get a runtime exception from EF.
这是`NorthwindRepositoryCustomersAnd1998Orders:
private class CustomerDto : Customer { } // EF requires a shadow class to make the LINQ query work
public IQueryable<Customer> CustomersAnd1998Orders {
get
{
return ForCurrentUser(Context.Customers)
.Select(c => new CustomerDto {
CustomerID = c.CustomerID,
CompanyName = c.CompanyName,
ContactName = c.ContactName,
ContactTitle = c.ContactTitle,
Address = c.Address,
City = c.City,
Region = c.Region,
PostalCode = c.PostalCode,
Country = c.Country,
Phone = c.Phone,
Fax = c.Fax,
RowVersion = c.RowVersion,
Orders = c.Orders
.Where(o => o.OrderDate != null && o.OrderDate.Value.Year == 1998)
.ToList()
});
}
}
有点乏味,但如果你需要它,你就需要它。
“订单”过滤器选择 1998 年订购的订单(这是旧的 Northwind 数据)。 OrderDate
是 nullable<DateTime>
所以我们必须检查null
然后从 Value
中取出年份.
请注意,它的项目带有 .Select
条款进入 CustomerDto
, Customer
的一个私有(private)的、“不执行任何操作”的子类,所以从技术上讲我返回了 IQueryable<CustomerDto>
。但它确实有效。
NorthwindController.NorthwindRepositoryCustomersAnd1998Orders
没有背叛任何东西:
[HttpGet]
public IQueryable<Customer> CustomersAnd1998Orders() {
return _repository.CustomersAnd1998Orders;
}
像查询“客户”一样在 Breeze 客户端上查询,但不指定.expand
条款;服务器会处理这个问题。
有一个转折点。看看能否在 this test from DocCode 中检测到它:
var query = EntityQuery.from('CustomersAnd1998Orders')
.where('CompanyName', 'startsWith', 'C')
.orderBy("CompanyName")
.toType('Customer'); // Essential ... unless fix with a JsonResultsAdapter
verifyQuery(newEm, query,
"Customers from 'CustomersAnd1998Orders' projection",
showCompanyNamesAndOrderCounts,
assertCustomersInCache,
assertOrdersInCache,
assertAllOrdersIn1998);
是的。您必须将结果转换为 Customer
因为线路上的类型是“CustomerDto”
$type: "DocCode.DataAccess.NorthwindRepository+CustomerDto, DocCode.DataAccess.EF"
但至少您可以在数据层上进行过滤( .where()
)和排序( orderBy()
)以及分页( take()
和 skip()
)。
在我看来,为这个结果付出的代价很小?
关于javascript - 用 Breeze 过滤扩展的 table ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27725284/