Включить отложенную загрузку при запросе URL-адреса OData

#c# #odata #lazy-loading #asp.net-web-api2

#c# #odata #отложенная загрузка #asp.net-web-api2

Вопрос:

Кажется, что при возврате IEnumerable из запроса OData конечной точки веб-API он перечисляет выполняет ускоренную загрузку перед применением параметров запроса. Вот что я имею в виду:

SomeType:

 public class SomeType
{
    public int SomeProp { get; set; }
}
  

Конечная точка:

 public class SomeTypeController : ApiController
{

    [EnableQuery]
    public IEnumerable<SomeType> Get()
    {

        return GetSomeTypes();

    }
    IEnumerable<SomeType> GetSomeTypes()
    {
        for (var i = 0; i < 10; i  )
        {

            Trace.WriteLine(i);

            yield return new SomeType { SomeProp = i };
        }
    }
}
  

при запросе /api/sometype?$top=2 я ожидал бы отследить 2 строки (0,1), но вместо этого я вижу, что цикл продолжается до конца.

Я ожидаю такого же поведения, как при вызове Take (2) перед возвратом:

Конечная точка:

 public class SomeTypeController : ApiController
{

    [EnableQuery]
    public IEnumerable<SomeType> Get()
    {

        return GetSomeTypes().Take(2);

    }
    IEnumerable<SomeType> GetSomeTypes()
    {
        for (var i = 0; i < 10; i  )
        {

            Trace.WriteLine(i);

            yield return new SomeType { SomeProp = i };
        }
    }
}
  

Есть ли какой-либо способ включить отложенную загрузку для параметров запроса OData?

Параметры запроса — единственная причина, по которой я использую OData, поэтому приветствуются альтернативы, которые могут реализовать параметры автоматического запроса.

Ответ №1:

IEnumerable перечисляется 10 раз, потому что применяется orderby по умолчанию.

Такое поведение разработано, потому что $ top требует стабильной сортировки.

Если вы этого не хотите, вы можете установить для EnsureStableOrdering значение false .

     [EnableQuery(EnsureStableOrdering = false)]
    public IEnumerable<SomeType> Get()
    {
        return GetSomeTypes().Take(2);    
    }