【问题标题】:Breeze filtering .Expand on server side微风过滤。在服务器端展开
【发布时间】:2014-03-18 21:22:26
【问题描述】:

我正在尝试BreezeJS。有一个要求,我可以在客户端代码中使用.expand,但是基于用户的role,服务器端不会返回.expand请求类型的所有记录。我试图创建一个自定义的BreezeQueryable 属性并覆盖一个方法来完全过滤掉额外的数据,只是为了尝试。但它抛出了一个异常。

我没有看到任何可以在服务器端执行此操作的入口点。

请指导我正确的方向,或者如果不可能,请告诉我。我只能访问通用IQueryable,如何对此执行查询?

这里有一些示例代码:

服务器:

[BreezeController]
[EnableCors("*", "*", "*")]
public class MyDataController : ApiController
{
    readonly EFContextProvider<MyDbContext> _contextProvider;

    public MyDataController()
    {
        _contextProvider = new EFContextProvider<MyDbContext>();
        _contextProvider.Context.Configuration.ProxyCreationEnabled = false;
        _contextProvider.Context.Configuration.LazyLoadingEnabled = false;
    }

    // GET api/<controller>
    //Trying to use a custom attribute to filter data here
    [CustomBreezeQueryable(AllowedQueryOptions = AllowedQueryOptions.All)]
    [HttpGet]
    public IQueryable<MyData> GetAllData()
    {
        var data = _contextProvider.Context.MyData;
        return data;
    }
}

public class CustomBreezeQueryableAttribute : BreezeQueryableAttribute
{
    public override IQueryable ApplyQuery(IQueryable queryable, 
                       ODataQueryOptions queryOptions)
    {
        var data = base.ApplyQuery(queryable, queryOptions);
        //trying to filter out MyDataHistory for MyData for testing, 
        //it throws exception
        //data = data.OfType<MyDataHistory>(); 
        return data;
    }
}

客户端:

breeze.EntityQuery.from("GetAllData").expand('MyDataHistory')
                   .using(this.manager)
                   .execute()
                   .then((data) => {               
                        console.log(data.results[0]);
                        def.resolve(data.results);
                    });

这是我在使用OfType 时得到的exception,我想过滤,反正不使用它。

{"DbOfTypeExpression requires an expression argument with a polymorphic result type that is compatible with the type argument."}

【问题讨论】:

  • 你得到什么异常?

标签: c# asp.net-web-api2 breeze


【解决方案1】:

不完全确定我是否理解您的问题,但您可以通过如下所示的 EF“包含”在服务器端执行“扩展”:

 [HttpGet]
 public IQueryable<Customer> CustomersAndOrders() {
   var custs = ContextProvider.Context.Customers.Include("Orders");
   return custs;
 }

这将返回 'Customer' 对象,每个对象的 'Orders' 属性已完全填充并加载到 Breeze 缓存中。

如果你想真正抑制服务器上给定资源名称的“扩展”,你可以使用 [BreezeQueryableAttribute]。请注意,以下示例中支持的操作列表中省略了 AllowedQueryOptions.Expand

[HttpGet]
[BreezeQueryable(AllowedQueryOptions = AllowedQueryOptions.Filter | AllowedQueryOptions.Skip | AllowedQueryOptions.Top | AllowedQueryOptions.OrderBy)]
public IQueryable<Employee> Employees() {
  return ContextProvider.Context.Employees;
}

[BreezeQueryableAttribute] 支持与此处描述的 Microsoft 的 [QueryableAttribute] 相同的参数:http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options

如果您想实际限制/过滤扩展的内容,则只能通过自己执行过滤扩展来完成,可能借助通过“withParameters”传递给方法的参数来完成(这是因为 EF 还没有支持对“包含”进行过滤。我没有测试下面的示例,但总体思路应该可行。

[HttpGet]
public IQueryable<Employee> Employees(double minWeight) {
  var emps = ContextProvider.Context.Employees.Include("Orders").ToList();
  // remove selected orders from what gets returned to the client.
  emps.ForEach(emp => {
    var ordersToRemove = emp.Orders.Where(o => o.Freight < minWeight).ToList();
    ordersToRemove.ForEach(o => emp.Orders.Remove(o));
  });
  return emps;
}

【讨论】:

  • 是的,我知道。我的问题是我想在客户端使用 .expand 时控制(在服务器中)返回的实体
  • 您好,我也对如何更好地控制服务器端的 .expand 功能非常感兴趣(现在看来,我的控制器只是被绕过了,因此业务逻辑被忽略了...... )
  • 您可以使用 [BreezeQueryableAttribute] 抑制服务器对给定资源名称执行任何“扩展”的能力。它支持与此处描述的 Microsoft 的 [QueryableAttribute] 相同的参数:asp.net/web-api/overview/odata-support-in-aspnet-web-api/… 只需从支持的操作列表中省略 AllowedQueryOptions.Expand。
猜你喜欢
  • 2022-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-17
  • 1970-01-01
相关资源
最近更新 更多