Бриз фильтрации. Расширить на стороне сервера
Я пытаюсь 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;
}