我一直在关注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”指的是什么?
我一直在努力寻找关于这个特定主题的博客/文章和教程但是难以捉摸..任何额外的阅读材料都将非常感谢,专注于上述签名等......
答案 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的第一件商品以及ProductInfo
和Order
相关实体。