我需要使用LINQ在ADO.NET模型中执行查询。我有一个EF类,用于我的web商店WebStoreEntities
的数据库,我需要在表Products
中找到目前正在打折的所有产品。WebStoreEntities
的实例称为webStoreDB
。
我已经有了一种从数据库中查询所有产品的方法:
public IList<Products> GetAllProducts()
{
return webStoreDB.Products.ToList();
}
为了编写一个具有签名IList<Products> GetAllDiscountProducts()
的方法来检索所有折扣产品,是否更快地编写:
return webStoreDB.Products.Where(m => Equals(m.discounted, 1)).ToList();
或
return GetAllProducts().Where(m => Equals(m.discounted, 1)).ToList();
Linq使用流和延迟执行,因此在调用ToList()
之前,您的查询尚未在数据库上下文中执行。
(您应该知道您在这里对实体使用linq,所以您的linq被组成一个sql查询,然后执行)
GetAllProducts()
调用ToList()
:
此时,sql被发送到数据库,执行,然后返回内存对象。这些内存中的对象然后由该部分进行过滤:.Where(m => Equals(m.discounted, 1)).ToList();
(现在这是Linq To Objects的一部分)
这是一个巨大的障碍,因为它将执行sql查询以返回所有产品(=>SELECT * FROM PRODUCTS
)。如果你有一百万件产品,它们都会在记忆中被退回!!
我推荐HRH Jon Skeets Edulinq系列,它应该能让你很好地理解延迟执行。特别是关于.Where();
的文章
return webStoreDB.Products.Where(m => Equals(m.discounted, 1)).ToList();
这是更快的,因为过滤是在数据库中完成的,作为
return GetAllProducts().Where(m => Equals(m.discounted, 1)).ToList();
过滤将在客户端的内存中进行。基本上,当提供者是某个关系数据库时,针对IQuerable接口发出的LINQ语句将被转换为SQL。
但是,如果您使用带有IEnumerable接口的LINQ,那么查询将在内存中执行。