LINQ如何在内部工作?
我喜欢在.net上使用LINQ,但我不知道如何在内部工作?
有谁知道吗?
THKS。
询问有关LINQ的特定方面更有意义。 这有点像问“Windows如何工作”,否则。
LINQ的关键部分对于我来说,从C#的angular度来看:
- expression树。 这些代码是数据的表示forms。 例如,expression式树可以表示“获取string参数,调用Length属性并返回结果”的概念。 这些数据存在而不是编译代码的事实意味着LINQ提供程序(如LINQ to SQL)可以分析它们并将它们转换为SQL。
-
Lambdaexpression式。 这些是这样的expression式:
x => x * 2 (int x, int y) => x * y () => { Console.WriteLine("Block"); Console.WriteLine("Lambda"); }
Lambdaexpression式被转换成委托或expression式树 。
-
匿名types。 这些是这样的expression式:
new { X=10, Y=20 }
这些仍然是静态types的,只是编译器用属性
X
和Y
为你生成一个不可变types。 这些通常与var
,允许从初始化expression式中推断出局部variables的types。 -
查询expression式。 这些是这样的expression式:
from person in people where person.Age < 18 select person.Name
这些由C#编译器转换为“正常”的C#3.0(即不使用查询expression式的表单)。 之后应用重载parsing等,这对于能够使用具有多种数据types的相同查询语法而言是绝对关键的,而不需要编译器具有诸如Queryable之类的types的任何知识。 上面的expression式将被翻译成:
people.Where(person => person.Age < 18) .Select(person => person.Name)
-
扩展方法。 这些静态方法可以像使用第一个参数types的实例方法一样使用。 例如,像这样的扩展方法:
public static int CountAsciiDigits(this string text) { return text.Count(letter => letter >= '0' && letter <= '9'); }
然后可以像这样使用:
string foo = "123abc456"; int count = foo.CountAsciiDigits();
请注意,
CountAsciiDigits
的实现使用另一个扩展方法Enumerable.Count()
。
这是相关的语言方面的大部分。 然后是标准查询运算符的实现,在LINQ提供程序中,如LINQ to Objects和LINQ to SQL等。我有一个关于如何相当简单地实现LINQ到对象的演示 – 它在C#的“演讲”页上,在深度网站。
提供程序(如LINQ to SQL)的工作方式通常是通过Queryable
类。 它们的核心是将expression式树转换为其他查询格式,然后构造适当的对象,并执行那些进程外查询的结果。
这是否涵盖了你感兴趣的一切? 如果有什么特别的东西你仍然想知道,只需编辑你的问题,我会去的。
在一个简单的表单中,编译器将您的代码查询转换成一堆generics类和调用。 在Linq2Sql的情况下,使用DbCommand,DbDataReader等构造并执行dynamicSQL查询。
假设你有:
var q = from x in dc.mytable select x;
它被转换成以下代码:
IQueryable<tbl_dir_office> q = dc.mytable.Select<tbl_dir_office, tbl_dir_office>( Expression.Lambda<Func<mytable, mytable>>( exp = Expression.Parameter(typeof(mytable), "x"), new ParameterExpression[] { exp } ) );
很多的generics,巨大的开销。
LINQ基本上是C#3.0离散function的组合:
- 局部variablestypes推断
- 自动属性(在VB 9.0中没有实现)
- 扩展方法
- lambdaexpression式
- 匿名types初始值设定项
- 查询理解
欲了解更多关于到达那里(LINQ)的信息,请参阅LANGNET 2008中的Andersvideo:
基本上LINQ是一些语言工具(编译器)和一些框架扩展的混合物。 所以当你编写linq查询时,它们会使用适当的接口(如IQuerable)来执行。 另请注意,运行时在linq中没有任何作用。
但是,在简短的回答中,很难做出正确的判断。 我build议你阅读一些书,让自己在这里。 我不确定这本告诉你Linq内部的书,但是Linq in Action给了我一个很好的帮助。
我有一个小的C#程序,演示了C#中LINQ的实现。
class Program { static void Main(string[] args) { //Eventhough we call the method here, it gets called ONLY when the for loop is executed var Cities = LinQFunction(new List<string>() { "Bangalore", "Mysore", "Coorg", "Tumkur", "Kerala", "TamilNadu" }); //LinQFunction() gets callled now foreach(var city in Cities) { Console.WriteLine(city); } } //This function is called ONLY when the foreach loop iterates and gets the item from the collection static IEnumerable<string> LinQFunction(List<string> cities) { foreach (var item in cities) { //Return each 'item' at a time yield return item; } } }
使用适当的断点。