si2030 si2030 - 19 days ago 5
C# Question

Generic Repository pattern and Understanding the syntax

I have been looking at Chris Sakell's blog and in particular the ASP.Net API implementations.

I am having trouble with the actual syntax of his generic repository implementation. I would someone to explain simply and in detail the syntax and then also how to use it in the controller.

First, I am having trouble understanding the following method signature:

public T GetSingle(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includeProperties)


This is the signature..


  • whats the meaning of "Expression"?

  • Why do you need to create an expression tree

  • whats the meaning of "predicate"?

  • whats the meaning of "includeProperties"?



The method for this signature is:

public T GetSingle(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includeProperties)
{
IQueryable<T> query = _context.Set<T>();
foreach (var includeProperty in includeProperties)
{
query = query.Include(includeProperty);
}

return query.Where(predicate).FirstOrDefault();
}


Finally, how do I use this - while understanding what "includeProperty" refers to?

I have been trying to find blogs/articles and tutorials on this specific topic buts elusive.. any extra reading material would be greatly appreciated focusing on the above signature etc...

Answer
  • An Expression represents any element of code - a method, a parameter, a field, an if-else statement, etc.

    The Expression API serves as a mechanism to turn code into queryable information.

    An expression tree is an aggregation of expressions (a programming language statement).
    It is especially useful when communicating with a data store driver or implementing one, since it enables the driver vendor to translate C# code into the data store's language (SQL would be one example).

  • A Predicate is a function which accepts a non empty set of parameters (one or more) and returns a boolean value. example: "Are you ill?" "Is it rainy and warm?" etc.

  • The method in question simply returns the first item from a data store, for which the parameter predicate returns true. It does not necessarily map all of the values present in the data store into the returned instance- but instead returns only the values which were specified by the includeProperties expression.

Consider the following POCO:

class Trump
{
  public int Make {get;set;}
  public string America {get;set;}
  public double Great {get;set;}
  public float Again {get;set;}
}

We can choose to query the data store for instances of said type, provided that their 'Make' value is greater than 2016, and only return the values for the 'America' and 'Great' Properties, like so:

Trump trump = Single<Trump>(t=>t.Make>2016, t=>t.America, t=>Great);

Feel free to ask for any clarifications.