javascript - 用 Breeze 过滤扩展的 table

标签 javascript entity-framework breeze

我在我的项目中使用 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 数据)。 OrderDatenullable<DateTime>所以我们必须检查null然后从 Value 中取出年份.

请注意,它的项目带有 .Select条款进入 CustomerDtoCustomer 的一个私有(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/

相关文章:

javascript - 对象数据源的 AngularJS ngOptions 表达式 - 是否可以将属性键存储在某处?

javascript - 如何在特定页面停止 jQuery 插件?

linq - Breeze where 查询 EF 中带有中间实体的多对多

c# - 如何在不使用 EF 的情况下使用 Breeze 保存更改?

mvvm - Durandal : multiple views for one viewmodel

javascript - 无法将 Jquery 对象复制到 Jquery 对象中

javascript - 窗口对象和属性持久化

c# - 具有 .Net Core Identity 的 Multi-Tenancy DbContext 的 IoC DI

ios - 是否可以在 Monotouch/Xamarin 中实现 Entity Framework 的 Code First?

c# - 使用 LINQ 选择最频繁的值