I'm reading up on generic repositories. I keep stumbling into bits of code that I don't understand. I don't know if there's a specific name for them or not.
This is the most complicated example I've seen:
IEnumerable<T> GetByQuery(
Expression<Func<T, bool>> query = null,
Func<IQueryable<T>, IOrderedQueryable<T>> orderby = null,
string includeProperties = "");
I know it (whatever it is) apparently returns an IEnumerable
, but I have no idea how to read that mess of gobbledygook let alone how to go about using it.
Edit: I'm more interested in knowing what that's an example of than a breakdown of that specific example. I need to know what they're called before I can find something that explains the syntax. LINQ??
Edit 2: I'm asking a much, much simpler question than the one being answered. All I want to know is "what are a few search terms I can use in order to research the above code?"
Note, all of this is an extremely educated guess, based on how IQueryable<T>
work.
Breaking it down into three parts:
Expression<Func<T, bool>> query = null
This is a where clause, it's the same signature that's passed to the Where
extension method on IQueryable<T>
.
You'd pass an expression, which is represented in code the same way that a lambda is; the C# compiler knows that the parameter is looking for an Expression
and will compile it into an expression tree and not a delegate.
For example, assuming T
is a Person
class with an int
property Age
, you could filter out any Person
returned by the IQueryable<Person>
that is 30 years or older with the following:
p => p.Age > 30
Func<IQueryable<T>, IOrderedQueryable<T>> orderBy
This is just a delegate which if provided, will allow you to set an order. Assuming you want the Person
instances ordered by age, you'd use:
q => q.OrderBy(p => p.Age)
This is because the return type is IOrderedQueryable<T>
, which how extension methods such as ThenBy
and ThenByDescending
pop up only after you call OrderBy
and OrderByDescending
; those extension methods are only defined on IOrderedQueryable<T>
(it's little more than a marker interface).
includeProperties
This gives away that it's using the Entity Framework underneath the covers. When you call Include
in the Entity Framework, it allows you to get related entities (via foreign key) and load the entities related to the entity being returned in the query.
Let's say the Person
class has a property Father
of type Person
. If you wanted to query Person
instances and have the Father
property returned as well, then you'd call Include("Father")
to indicate that not only should Entity Framework get the instances of Person
, but it should resolve the Father
relationship as well.
IEnumerable<T>
return type
This is returned so that you don't have access to the IQueryable<T>
instance and forces you to materialize the result set (as you iterate through it).
An implementation that does this should be returning the a materialized list (IReadOnlyCollection<T>
), or something that is not just (assumedly) a cast of IQueryable<T>
to IEnumerable<T>
.
It's also an indication of the trust that the writer of the method has for the clients; as IQueryable<T>
isn't returned, it indicates that it doesn't trust clients to not make inefficient database calls (which is a valid concern).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With