您的位置:知识库 » 数据库

走进Linq-Linq to SQL源代码赏析,通过Linq to SQL看Linq

作者: 横刀天笑  来源: 博客园  发布时间: 2008-09-24 12:06  阅读: 9342 次  推荐: 0   原文链接   [收藏]  

系列文章导航:

走进Linq--Linq横空出世篇

走进Linq-辉煌的背后

走进Linq-Linq大观园

不能不说的C#特性-对象集合初始化器

不能不说的C#特性-匿名类型与隐式类型局部变量

不能不说的C#特性-扩展方法

不能不说的C#特性-匿名方法和Lambda表达式

不能不说的C#特性-迭代器(上)及一些研究过程中的副产品

不能不说的C#特性-迭代器(下),yield以及流的延迟计算

走进Linq-Linq to Objects(上)基础篇

走进Linq-Linq to Objects(下)实例篇

走进Linq-Linq to SQL感性认识篇

走进Linq-Linq to SQL How do I(1)

走进Linq-Linq to SQL How do I(2)

走进Linq-Linq to SQL How do I(3)

走进Linq-How do I(4)拾遗补零篇第一节

走进Linq-Linq to SQL源代码赏析 Table的获取过程

走进Linq-Linq to SQL源代码赏析之Provider的初始化

走进Linq-Linq to SQL源代码赏析,通过Linq to SQL看Linq


 

既然如此那我们就得看看Table<TEntity>GetEnumerator方法了:

public IEnumerator<TEntity> GetEnumerator()
{
   
return ((IEnumerable<TEntity>)this.context.Provider.Execute(Expression.Constant(this)).ReturnValue).GetEnumerator();
}

从这里可以看出它是通过调用IProviderExecute方法。

关于Execute更深层次的内容,在本篇中并不涉及,你只要知道它根据Lambda表达式生成SQL语句,然后对数据库进行操作就OK了。

如果存在这样一个查询:

Var result = posts.Where(p=>p.id==1);

这样的一个查询到底会发生什么呢?实际上我们根本无从得知,如果posts是一个内存中的集合那么就是在内存中进行对象的筛选,实际上就是执行一下一个foreach,然后将符合p.Id == 1这个条件的所有Post对象都添加到返回的集合中;如果posts是一个Table<TEntity>对象,那么这个查询最后将生成SQL语句对数据库进行操作。一样是Where,传入的参数也是Lambda表达式,为什么产生的结果却不同呢?两个Where真的是相同的么?

实际上在我们对内存中的集合使用Where等扩展方法的时候是使用Enumerable类对IEnumerable<T>的扩展。

我们再来看看Table<TEntity>,它实现了IQueryable<T>接口,IQueryable<T>有一个IQueryProvider类型的成员。在System.Linq命名空间下还有一个Queryable类,这个类是对IQueryable<T>接口进行扩展的。那现在看来Linq to SQLLinq to Objects并没有什么直接关系,唯一的就是靠IEnumerable<T>这个建立起桥梁,让它们查询的方式语言都统一。

我们再来看看EnumerableQueryable中的扩展方法有什么不同:

Enumerable中的扩展方法接受的一般都是委托类型的参数,而Queryable中接受的却是Expression,但为什么它们都可以接受Lambda表达式作为参数呢?

神奇的赋值符号“=

Func<int,bool> IsTrue = x=>x==5;

Expresssion<Func<int,bool>> IsTrue = x =>x==5;

0
0

数据库热门文章

    数据库最新文章

      最新新闻

        热门新闻