3

I know this was partly asked before, but none of the questions completely answer this.

What happens when one uses LINQ to SQL to retrieve data from the database?

I've read the following questions:

What is unclear to me is: at which point is the database accessed? When are the queries run?

If I run the following query, how will it translate to a SQL query?

    DatabaseDataContext db = new DatabaseDataContext();
    var users = from x in db.Users 
                where x.Rank > 10 
                orderby x.RegistrationDate descending
                select x)
                .Skip(pageIndex * recordCount)
                .Take(recordCount);

And then, later, if I try to access some property of some user, how will the query be constructed (this is partly answered here)?

var temp = users.ToList()[0].SomeProperty;

Basically, what I really want to know is how the LINQ to SQL works under the hood, how it goes from the C# language statement to the SQL and how it is optimized.

4

3 回答 3

7

LINQ to SQL 框架将获取您的 Linq 查询,它实际上是一个表达式树,然后将这个表达式树转换为一个纯 SQL 查询。请参阅如何:使用表达式树构建动态查询

事实上,每个表达式树都可以翻译成您需要的任何语言或数据库。您将有不同的提供者为不同的数据库( OracleSQLite等)实现 IQueryable 。请注意,LINQ to SQL 是 LINQ to SQL Server 的缩写。另一方面,实体框架/LINQ to Entities 可以更容易地扩展到其他数据库。

这里的重点是IQueryable接口,它包含一个表达式树,以及提供程序的实现。有关如何实现提供程序的示例,即如何从表达式树转换为查询,请参阅LINQ:构建 IQueryable 提供程序

这是一个片段,可以让您了解引擎盖下发生的事情:

if (select.OrderBy != null && select.OrderBy.Count > 0) 
{
    this.AppendNewLine(Indentation.Same);
    sb.Append("ORDER BY ");
    for (int i = 0, n = select.OrderBy.Count; i < n; i++) 
    {
        OrderExpression exp = select.OrderBy[i];
        if (i > 0) 
        {
            sb.Append(", ");
        }
        this.Visit(exp.Expression);
        if (exp.OrderType != OrderType.Ascending) 
        {
            sb.Append(" DESC");
        }
    }
}
于 2013-11-05T09:42:31.743 回答
3

只要您需要结果,查询就会运行。

var qry = (from x in db.Users where x.Rank > 10 orderby x.RegistrationDate descending
            select x)

此时查询尚未运行,因为您尚未使用结果。
将其放入 aforeach或将其转换为 aList并强制查询 Materiliaze。

经验法则是:每当GetEnumerator在 IQueryable 上调用 - 查询被强制实现(至于“到数据库并获取实际记录”)

于 2013-11-05T09:44:36.870 回答
1

所有你想知道的都在 MSDN 上关于 LINQ to SQL 的文章中得到解答:http: //msdn.microsoft.com/en-us/library/bb425822.aspx

顺便说一句,如果您只想使用结果的一部分,如上面的代码,最好修改您的查询,如下所示:

var prop = (from x in db.Users 
                where x.Rank > 10 
                orderby x.RegistrationDate descending
                select x.SomeProperty)
                .Skip(pageIndex)
                .First()
                .Select(x => x);

您在查询中所做的优化通常比系统如何在后台执行窥视孔优化更重要......

于 2013-11-05T09:44:17.867 回答