Reputation: 3021
It seems when returning IEnumerable
from Web API Endpoint OData Query it enumerates \ does eager loading before applying query options.
Here is what I mean:
SomeType:
public class SomeType
{
public int SomeProp { get; set; }
}
Endpoint:
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 };
}
}
}
when requesting /api/sometype?$top=2
I would expect to Trace 2 lines (0,1) but instead I see loop continuing to the end.
I expect behaviour same as calling Take(2) before returning:
Endpoint:
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 };
}
}
}
Is there any way to switch on Lazy loading for OData query options?
Query options is the only reason I use OData, so alternatives that can implement automatic query options are welcome.
Upvotes: 3
Views: 1835
Reputation: 2995
The IEnumerable enumerates 10 times because default orderby is applied.
This behavior is by design because $top requires a stable sort.
If you don't want this, you can set the EnsureStableOrdering with false.
[EnableQuery(EnsureStableOrdering = false)]
public IEnumerable<SomeType> Get()
{
return GetSomeTypes().Take(2);
}
Upvotes: 2