Бриз фильтрации. Расширить на стороне сервера

Я пытаюсь 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."}

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;
}
Другие вопросы по тегам