2012-08-02 55 views
1

我是C#和LINQ的新手,但后者非常酷。除了我不知道这里发生了什么:在SQL中使用LINQ查询:语法差异会导致挂起和SQLException?

我有以下一段代码,它按预期方式运行;它排序,选择前100个记录:

IEnumerable<workerLog> query = 
    (from record in _gzClasses.workerLogs     
    orderby record.workerID, record.timeStamp ascending     
    select record).Take(100); 

foreach(var record in query) 
{ 
    Console.WriteLine(record.timeInSession.ToString()); 
} 

,但是当我这样做,同样的线路进行打印,但随后的程序挂起了一下,则抛出SQLException说服务器超时。

IEnumerable<workerLog> query = 
    from record in _gzClasses.workerLogs     
    orderby record.workerID, record.timeStamp ascending     
    select record; 

foreach(var record in query.Take(100)) 
{ 
    Console.WriteLine(record.timeInSession.ToString()); 
} 

世界上有什么不同?它与LINQ查询的执行方式有什么关系?来自Java世界,这是没有意义的。

+0

尝试运行sql分析器并查看正在执行的查询。有区别吗? – 2012-08-02 22:05:31

回答

3

这里是错误:

IEnumerable<workerLog> query = 

通过迫使它IEnumerable<WorkerLog>,你已经打破“成分”,这意味着SQL服务器认为你已经要求所有的数据,在接收你会选择只关心前100行。如果你使用IQueryable<WorkerLog>代替(或只是var),那么就可以通过“撰写”带(100)到SQL和问题:

select top 100 ... 

注意的是,在第一个例子中,你只之后强制IEnumerable<WorkerLog>它已经组成,所以,工作好.... ish。

基本上,IQueryable<T>是可组合的API,它可以从多个操作中获得有趣的TSQL。 IEnumerable<T>是LINQ-to-Objects,它在c#中进行过滤/ etc而不是在SQL中。

+0

谢谢。我必须从我的屁股中取出IEnumerable。 但是,如果我切换到'var',会不会在将'foreach'循环转换回'workerLog'时出现问题? 此外,有什么具体关于'IEnumerable'会导致SQL错误? – 2012-08-02 23:19:47

+0

@AndrewMao不,使用'var'没有问题; 'var'只是意味着“编译器:你可以看到这是什么回报 - 自己弄清楚类型”,这意味着它将是'IQueryable ' - 因此完全没有问题知道每个都是'WorkerLog'。重新“具体的东西” - 是的;表中有多少行?在查询100行时,查询200万行(或其他)可能会导致超时。 – 2012-08-03 05:32:23

+0

感谢您解释var问题。我试图问另一个基于LINQ的问题,但似乎我的帐户由于某种原因被禁止:( – 2012-08-03 23:58:05