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

时间:2016-11-20 09:07:41

标签: c# generics linq-expressions

我一直在关注Chris Sakell's博客,特别是ASP.Net API实现。

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

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

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

这是签名..

  • 什么是“表达”的含义?
  • 为什么需要创建表达式树
  • 什么是“谓词”的含义?
  • 是什么意思“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”指的是什么?

我一直在努力寻找关于这个特定主题的博客/文章和教程但是难以捉摸..任何额外的阅读材料都将非常感谢,专注于上述签名等......

2 个答案:

答案 0 :(得分:4)

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

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

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

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

  • Predicate是一个函数,它接受一组非空参数(一个或多个)并返回一个布尔值。例子:

     
     bool IsBroken(Car car);
     bool IsMildRainExpected(WeatherForecast forecast, int threshold);
    

  • 有问题的方法只返回数据存储中的第一项,参数谓词返回true。它不一定将匹配对象中存在的所有字段映射到返回的实例中 - 而是仅映射includeProperties表达式指定的值。

考虑以下POCO:

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

我们可以选择在数据存储中查询所述类型的实例,只要它们的“Make”值大于2016,并且只映射“America”和“Great”属性的值,如下所示:

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

随时要求澄清。

答案 1 :(得分:2)

让我们逐一回答您的问题

  

Expression<T>的含义是什么?

  

为什么需要创建表达式树?

在此实现中,作者使用Entity Framework,因此在幕后有IQueryable接口。此接口提供了将m => m.Id == 1等表达式传递给SQL查询语法的方法。为了能够将一个表单转换为另一个表单,实体框架需要知道如何这个表达式的功能。这是更广泛的主题,因此请考虑观看Jon Skeet and Scott Allen explaining difference between IEnumerable and IQueryable

  

是什么意思&#34;谓词&#34;?

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

  

是什么意思&#34; includeProperties&#34;?

使用Entity Framework,您不仅可以检索与该实体相关的一个实体,还可以检索那些实体。为此,您可以使用Include功能。然后,您明确告知要检索哪些相关实体,并使用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相关实体。