Breeze filtering .Расширить на стороне сервера

Я пробую 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);
                    });

Это exception, который я получаю при использовании OfType, и я хотел бы отфильтровать, а не использовать его в любом случае.

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

person AD.Net    schedule 18.03.2014    source источник
comment
Какое исключение вы получаете?   -  person Adel Sal    schedule 19.03.2014


Ответы (1)


Не совсем уверен, что понимаю вашу проблему, но вы можете выполнить «расширение» на стороне сервера с помощью «Включить» EF, как показано ниже:

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

Который будет возвращать объекты «Клиент», каждый со своим свойством «Заказы», ​​полностью заполненным и загружаемым в кеш Breeze.

Если вы хотите фактически подавить «расширение» на сервере для данного имени ресурса, вы можете использовать атрибут [BreezeQueryableAttribute]. Обратите внимание, что AllowedQueryOptions.Expand отсутствует в списке поддерживаемых операций в приведенном ниже примере.

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

[BreezeQueryableAttribute] поддерживает те же параметры, что и [QueryableAttribute] Microsoft, описанные здесь: 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;
}
person Jay Traband    schedule 18.03.2014