2013-03-08 4 views
2

У меня есть этот метод репозитория:с использованием OData Queryable с репозиторием?

public IQueryable<TModel> GetAll() 
{ 
    using (var context = new DatabaseContext()) 
    { 
     return context.Set<TModel>().AsQueryable(); 
    } 
} 

TModel, где художник-модель .. в любом случае

И тогда я это действие в мой контроллер:

// GET api/artist 
[Queryable] 
public IQueryable<ArtistModel> Get() 
{ 
    return _repo.GetAll().AsQueryable(); 
} 

Теперь .. если Я бы изменил метод репозитория, чтобы вернуть список, а также добавить .ToList для моего результата .. тогда это будет отлично работать. Но тогда независимо от того, какой запрос OData приходит. Я бы все же сначала выполнил «получить весь запрос» .. превратил их в список, а затем я выполнил бы мой запрос OData к этому списку.

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

Теперь у меня есть проблема с DbContext получать расположенную сразу за пределами использования .. но я все еще нужен, чтобы закрыть DbContext, а некоторые, где, как некоторые. .

Любые идеи?

+1

Часть вопроса в вашем мышлении вызывает метод GetAll(), потому что на самом деле это не происходит. Он возвращает объект запроса, чей POTENTIAL SET объектов - все из них. Если вы вдруг добавите ToList() в GetAll(), то вы меняете контакт метода. – Rich

ответ

1

Последняя версия запрашиваемого расширения web api довольно запутанна, поскольку она настолько отличается от предыдущих версий. В новой версии вам нужно либо явно включить поддержку запросов, либо использовать новый класс параметров запроса. See this

Edit: Некоторые код этого, так как я сейчас нахожусь на столе

public IQueryable<TModel> GetAll(ODataQueryOptions opts) 
    { 
     var db = _repo.GetAll(); 
     return (IQueryable<TModel>) opts.ApplyTo(db); 
    } 
+0

Хорошо, но это не совсем покрывает мою проблему. Im affraid .. Дело в том, что я не хочу, чтобы делать .ToList в моем репо .., так как это вызовет базу данных .. заберите все строки в это .., а затем позже в моем контроллере OData-запрос будет затем запрашивать/фильтровать результат списка. Я хотел бы пропустить .ToList и выполнить OData-Query в базе данных с самого начала..так, я не нужно брать запись hughe строк из базы данных, которая может даже не «подгонять» запрос. – Inx

+0

Я знаю, что вы НЕ хотите получить всю базу данных. Я, честно говоря, не думаю, что вы прочитали всю информацию, которую я вам отправил. – Aron

+0

Я прочитал его еще раз :) .. извините за это .., но я не понимаю, где и как это избавляет и отключает мой объект dbcontext? .. так как я не хочу оставлять это соединение, просто закладывать и резервировать соединение в пуле .. является ли распоряжение и отключение, сделанное в ApplyTo? Поэтому, чтобы использовать этот подход, мне нужно было бы переписать свое репо на что-то вроде: public IQueryable GetAll() { var context = new DatabaseContext(); return context.Set () .AsQueryable(); ?? – Inx

2

Вы можете включить веб-API запрашиваемых через несколько способов,

  1. Поместите атрибут [Queryable] на ваши действия , Ваше действие может возвращать одно из них - IEnumerable<T>, IQueryable<T>, HttpResponseMessage с содержанием будучи ObjectContent<IQueryable<T>> или ObjectContent<IEnumerable<T>>, Task<IQueryable<T>>, Task<IEnumerable<T>>, Task<HttpResponseMessage> с теми же ограничениями, как раньше.

  2. Включить запрос по всему миру, выполнив configuration.EnableQuerySupport(). Это позволит запрашивать все методы, возвращающие IQueryable<T>.

  3. Использовать ODataQueryOptions<T> как указано here и вручную применить запрос самостоятельно.

А что касается вопроса DbContext утилизации, мы оцениваем запрос очень поздно в ленивой моде - когда форматировщик пишет ответ на поток. Таким образом, вы не должны распоряжаться DbContext в своем действии. Вместо этого удалите его вместе с контроллером, а затем переопределите метод контроллера Dispose и разместите его там. Web API заботится о времени жизни контроллеров и распоряжается контроллером при обработке запроса. Кроме того, вы также можете использовать метод Request.RegisterForDispose, чтобы распоряжаться любыми ресурсами, когда обработка запроса выполнена.

Смежные вопросы