虽然对使用IQueryable希望改善现有代码性能感到好奇,但我遇到了这个online test case。
为了测试所提出的例子的有效性,我:
按如下方式调用它们:
static void Main(string[] args)
{
GetCustomers();
GetRules();
}
public static IQueryable GetCustomers()
{
var db = new DbEntities();
return db.GetCustomers().AsQueryable();
}
public static IQueryable GetRules()
{
var db = new DbEntities();
return db.GetRules(null).AsQueryable();
}
跟踪SQL Server Profiler中的db调用
根据链接中提供的样本测试问题
因此,我们对数据库执行单个复杂查询(当调用.ToList()时),而不是分别检索两个集合并将它们连接到服务器端。
我明白只要我们返回IQueryable,就不会启动db调用,直到.ToList()在某一点被调用。
但是,在我提供的代码示例中:
我的期望是这些数据库调用不应该首先发生,因为我正在返回IQueryable。
发生了什么?
答案 0 :(得分:3)
可组合查询的想法仅适用于基于表达式树的动态查询。如果您调用存储过程,那么实际调用存储过程 - 您必须添加List<Customer>
这一事实通常意味着您实际上正在使用LINQ-to - 完全物化对象上的对象(例如IQueryable<T>
或类似对象),但只是将描述为可查询对象。那时候:已经太晚了 - 你已经执行了它。
可能可能以某种方式编写存储过程,但我不会依赖它。当人们谈论IQueryable<Customer> CustomersByRegion(string region)
=> db.Customers.Where(c => c.Region == region);
...
var data = from cust in CustomersByRegion("North")
where cust.Value > 10000
order by cust.Name
select new {cust.Id, cust.Name};
时,这并非真正的目标场景。而是用于以下事项:
where
其中两个单独的order by
由select Id, Name
from Customers
where Region = @p0 and Value > @p1
order by Name
和列的子选择组成,以创建撰写的 SQL查询,如:
{{1}}