From time to time I meet people trying to express an API in terms of IQueryable<T>
. This is almost always a bad idea. In this article I will explain why. In short, IQueryable<T>
this is one of the best examples of the Header Interface offered by the .NET framework. It is almost impossible to implement it completely.
This article is about the challenges of implementing an API based on an interfaceIQueryable<T>
. This is not a complaint about the interface as such. Other than that, this is not a claim to the wonderful LINQ methods available for the interfaceIEnumerable<T>
.
We can say that IQueryable<T>
this is one continuous violation of the Liskov substitution principle . I will use Postel's Law to explain why this is so.
The Sustainability Principle, also known as Postel's Law in honor of John Postel : "Be liberal in what you accept, and conservative in what you send."
Using IQueryable<T>
The first part of Postel's law, when applied to API design, is that the API should be liberal with respect to what it accepts . In other words, we are talking about input parameters. Thus, the receiving API IQueryable<T>
might look like this:
IFoo SomeMethod(IQueryable<Bar> q);
Is this API liberal enough ? Definitely not. Such an interface requires the calling code to pass an implementation IQueryable<Bar>
. According to the Liskov substitution principle, the program must remain correct for all interface implementations. This applies to both implementation IQueryable<Bar>
and implementation SomeMethod
.
IQueryable<T>
: (Query Provider). , Bar
, . , , - , , โ SQL. .
, ( ), ? SomeMethod
? , , , . , .
, , . , Query Objects , , .
IFoo FindById(int fooId);
IFoo FindByCorrelationId(int correlationId);
IEnumerable<IFoo> GetFoos(int page);
, . API, (Role Interfaces) , .
IQueryable<T>
, API , . , , . , IQueryable<T>
:
IQueryable<Bar> GetBars();
API ( ). , . , IQueryable <Bar>
, IQueryable <Bar>
.
? LSP, , IQueryable<Bar>
, . . ?
IQueryable<T>
โ . , IQueryable Microsoft. , , , , .
- Entity Framework ORMNotSupportedException
? . , , , LSP. , ,IQueryable<T>
, , .
, , , . , Entity Framework, Microsoft OData. , IQueryable<T>
, โ ( ). Null Object, IQueryable<T>
, , .
:
public interface IRepository
{
IQueryable<T> Query<T>();
}
LSP , , , , ( ) , . . , , ORM, , , , ORM. .
ORM, . . , . . , SQL Event Store.
โ .
- More about the device
IQueryable
andIQueryProvider
in the article " How IQueryable and LINQ Data Providers work ".- About creating your own query providers in the eponymous talk by Anton Tretyakov from DotNext Moscow 2019 .