Использование PredicateBuilder со службами WebAPI OData и EntityFramework

Я использую функцию запроса OData для своего одностраничного приложения. Недавно я попытался добавить некоторую фильтрацию на бизнес-уровне на основе разрешений пользователя, и это приводит к сбою моего запроса odata в определенных ситуациях.

Мой контроллер OData ссылается на класс моего бизнес-уровня, который возвращает IQueryable. Бизнес-уровень ссылается на первую модель базы данных Entity Framework.

На моем бизнес-уровне у меня есть следующее свойство.

public IQueryable<Job> Jobs
{
    get
    {
        IQueryable<Job> queryable = UnitOfWork.Jobs.AsExpandable();

        var predicate = PredicateBuilder.False<Job>();

        foreach (int clientID in userService.GetAllowedClientIds())
        {
            int temp = clientID;
            predicate = predicate.Or(p => p.ClientId == temp);
        }

        return queryable.Where(predicate);
        // I've tried returning this as .AsExpandable() again and as .AsQueryable() and neither change the result.
    }
}

Мой контроллер odata — это простой проход к BL.

[Queryable(MaxExpansionDepth = 3)]
public IQueryable<Job> Get()
{
    return jobService.Jobs;
}

Теперь, в зависимости от того, какие параметры запроса я передаю в URL-адресе, я получаю либо данные, либо "Cannot compare elements of type 'System.Collections.Generic.ICollection1[[AssociatedType]]'. Поддерживаются только примитивные типы, перечисляемые типы и типы сущностей."`

Например, /Jobs?$expand=LatestJobAllocations/Gang работает отлично, а /Jobs?$expand=JobLocationStructures не работает. Разница в том, что LatestJobAllocations — это представление, которое я добавил в модель, а JobLocationStructures — это таблица, а также Job и LatestJobAllocations — это отношение 1-0..1.

Если я добавлю пейджинг к неудавшемуся запросу, он чудесным образом сработает. /Jobs?$expand=JobLocationStructures&$inlinecount=allpages&$top=25&$skip=0 что было бы здорово, но я не могу использовать пейджинг для получения одного объекта /Jobs(1234)?$expand=JobLocationStructures&$inlinecount=allpages&$top=25&$skip=0 терпит неудачу, потому что пейджинг не разрешен на конечных точках с одним объектом.


person BenCr    schedule 18.06.2014    source источник
comment
Покажите код для userService.GetAllowedClientIds() и вашего класса Job.   -  person haim770    schedule 18.06.2014
comment
Работа - это просто сущность структуры сущности. GetAllowedClients возвращает IEnumerable<int>, на данный момент он просто возвращает new [] {1, 2, 3, 4, 5, 6};, потому что я не подключал его к чему-то более сложному.   -  person BenCr    schedule 18.06.2014
comment
Работа огромна, она слишком велика, чтобы публиковать ее в SO-вопросе. Однако в этом нет ничего особенного, он просто сопоставляется с таблицей с некоторыми связанными сущностями.   -  person BenCr    schedule 18.06.2014
comment
Что такое связанный тип? Кажется, что некоторая логика сравнения в предикате некорректна. Посмотрите, может ли это помочь: stackoverflow.com/questions/23937112/   -  person Feng Zhao    schedule 30.06.2014