Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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...

like image 532
si2030 Avatar asked Oct 28 '25 14:10

si2030


2 Answers

  • 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).

  • The Expression API is extremely useful, for instance, when communicating with a data store driver or when 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. examples:

     
     bool IsBroken(Car car);
     bool IsMildRainExpected(WeatherForecast forecast, int threshold);
    
  • 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 fields present in the matching object into the returned instance- but instead maps only the values which were specified by the includeProperties expressions.

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 map the values for the 'America' and 'Great' Properties, like so:

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

Feel free to ask for any clarifications.

like image 116
Eyal Perry Avatar answered Oct 30 '25 04:10

Eyal Perry


Let's answer your questions one by one

what's the meaning of Expression<T>?

and

why do you need to create expression tree?

In this implementation author uses Entity Framework, so behind the scenes there is IQueryable interface. This interface provides method for transferring expressions like m => m.Id == 1 to SQL query syntax. To be able transform one form to the other, Entity Framework needs to know how this expression does what it does. This is broader topic, so consider watching Jon Skeet and Scott Allen explaining difference between IEnumerable and IQueryable

whats the meaning of "predicate"?

Predicate could be explained as filter - it tells the query which elements to include in result. For example product => product.Cost > 3000 is a predicate. In video I already mentioned Jon Skeet also explains what predicate is.

whats the meaning of "includeProperties"?

Using Entity Framework you can retrieve not only one entity, but also those entities, that are related to that one. In order to do so, you use Include function. Then you're explicitly telling which related entities to retrieve and you use eager loading mechanism.

As for the usage. Let's assume you have following model

public class Product
{
    public int ID { get: set; }
    public ProductInfo ProductInfo { get; set; }
    public IEnumerable<Order> Orders { get; set; }
} 

Product product = genericRepository.GetSingle<Product>(p => p.Cost > 3000, p.ProductInfo, p.Orders)

With above statement you could retrieve first product with cost higher than 3000 along with ProductInfo and Order related entities.

like image 27
Paweł Hemperek Avatar answered Oct 30 '25 03:10

Paweł Hemperek