通用存储库模式和理解语法

Generic Repository pattern and Understanding the syntax

我一直在查看 Chris Sakell's 博客,尤其是 ASP.Net API 实现。

我在使用他的通用存储库实现的实际语法时遇到了问题。我希望有人简单而详细地解释语法,然后再解释如何在控制器中使用它。

首先,我无法理解以下方法签名:

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

这是签名..

这个签名的方法是:

    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();
    }

最后,我该如何使用它 - 同时理解 "includeProperty" 指的是什么?

我一直在努力寻找 blogs/articles 和关于这个特定主题的教程,但难以捉摸。任何额外的阅读 material 将非常感谢专注于上述签名等...

  • 表达式表示代码的任何元素 - 方法、参数、字段、if-else 语句等。

  • 表达式 API 用作将代码转换为可查询信息的机制。

  • 表达式树是表达式(编程语言语句)的集合。

  • 表达式 API 非常有用,例如,在与数据存储驱动程序通信或实现数据存储驱动程序时,因为它使驱动程序供应商能够将 C# 代码转换为数据存储的语言(SQL 就是一个例子)。

  • 谓词是一个函数,它接受一组非空参数(一个或多个)和 returns 一个布尔值。例子:

     
     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);

欢迎随时询问任何说明。

让我们一一回答你的问题

what's the meaning of Expression<T>?

why do you need to create expression tree?

在这个实现中作者使用了Entity Framework,所以在幕后有IQueryable接口。该接口提供了将 m => m.Id == 1 等表达式转换为 SQL 查询语法的方法。为了能够将一种形式转换为另一种形式,Entity Framework 需要知道 这个表达式如何做它所做的事情。这是一个更广泛的话题,所以考虑观看 Jon Skeet and Scott Allen explaining difference between IEnumerable and IQueryable

whats the meaning of "predicate"?

谓词可以解释为过滤器 - 它告诉查询要在结果中包含哪些元素。例如 product => product.Cost > 3000 是一个谓词。在我已经提到的视频中,Jon Skeet 也解释了谓词是什么。

whats the meaning of "includeProperties"?

使用 Entity Framework 您不仅可以检索一个实体,还可以检索与该实体相关的那些实体。为此,您使用 Include function. Then you're explicitly telling which related entities to retrieve and you use eager loading mechanism.

至于用法。假设您有以下模型

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)

使用上述语句,您可以检索成本高于 3000 的第一个产品以及 ProductInfoOrder 相关实体。