.NET 2.0运行时上的LINQ
启用LINQ的应用程序可以在仅安装.NET 2.0运行时的计算机上运行吗?
从理论上讲,LINQ只是语法糖,而且生成的IL代码应与.NET 2.0中的外观相同。
如何在不使用.NET 3.5库的情况下编写LINQ?它可以在.NET 2.0上运行吗?
解决方案
回答
不,因为尽管我们认为LINQ实际上只是语法糖,但实际上它大量使用了表达式树-.NET 2.0中缺少的一项功能。
话虽如此,.NET 3.5仅建立在.NET 2.0的基础上,这就是IL看起来不"不同"或者"特殊"的原因。
我看不出为什么不应该仅安装.NET 3.5 Framework的原因。 .NET 2.0一切都可以正常运行,请保证:)
回答
有一些"难题"涉及使用3.5框架中的System.Core.dll使其与.net 2.0一起运行,但是我个人不希望使用这样有些不稳定的基础。
参见此处:.NET 2.0上的LINQ支持
Create a new console application Keep only System and System.Core as referenced assemblies Set Copy Local to true for System.Core, because it does not exist in .NET 2.0 Use a LINQ query in the Main method. For example the one below. Build Copy all the bin output to a machine where only .NET 2.0 is installed Run
(需要.net 2.0 SP1,并且我不知道捆绑System.Core.dll是否违反了EULA)
回答
从理论上讲,是的,只要我们分发LINQ特定的程序集和任何依赖项即可。但是,这违反了Microsoft的许可。 Scott Hanselman写了一篇有关在ASP.NET 2.0上部署ASP.NET MVC的博客文章,这与我们要执行的操作类似。
回答
据我所知,LINQ库仅自框架3.0起可用。
如果要在Framework 2.0中使用类似的内容,则需要自己重新编写它:)或者找到类似的第三方库。我在这里只找到了一些信息,但也没有使我信服。
回答
我不确定C#。
但是,我确实知道,只要使用VS 2008编译器以2.0框架为目标,就可以编写不带3.5库的VB LINNQ代码。
但是,我们将必须自己实现一些LINQ方法。
LINQ使用语法转换将查询转换为可执行代码。基本上,它将采用如下代码:
dim q = from x in xs where x > 2 select x*4;
并将其转换为如下代码:
dim q = xs.where(function(x) x > 2).select(function(x) x * 4);
对于3.5框架附带的LINQ功能,这些方法被实现为IEnumerable或者IQueryable上的扩展方法(也有许多方法可用于数据集)。
默认的IEnumerable扩展方法在System.Linq.Enumerable中定义,如下所示:
<Extension()> public function Select(of T, R)(source as IEnumerable(of T), transform as Func(of T, R)) as IEnumerable(of R) 'do the transformation... end function
IQueryable扩展方法将表达式树而不是lambda作为参数。他们看起来像这样:
<Extension()> public function Select(of T, R)(source as IQueryable<T>, transform as Expression(of Func(of T, R)) 'build a composite IQueryable that contains the expression tree for the transformation end function
表达式树版本使我们能够获得提供给子句的表达式的树表示形式,然后可将这些表达式用于生成SQL代码(或者我们想要的任何其他代码)。
我们可能会在大约一天左右的时间内为对象创建自己的LINQ版本。一切都非常简单。
如果我们想使用DLINQ,那么事情会有些困难。
回答
没人提到LINQBridge很奇怪。这个小巧的项目是LINQ(IEnumerable,但没有IQueryable)及其依赖项(Func,Action等)向.NET 2.0的反向移植。和:
If your project references LINQBridge during compilation, then it will bind to LINQBridge's query operators; if it references System.Core during compilation, then it will bind to Framework 3.5's query operators.
回答
简短答案:
- LINQ to Objects:是(
IEnumerable <T>
) - LINQ to SQL /实体:否(
IQueryable <T>
) - LINQ to XML / DataSets:还没有?
在从VS2008定位.Net 2.0时,可以自动或者不费吹灰之力地看到有关.Net 3.5功能的问题。
基本上,只有"语法糖"和新的编译器(C3.0,VB 9.0)发出与2.0兼容的IL的任何东西都可以使用。这包括LINQ使用的许多功能,例如匿名类,作为匿名委托的lambda,自动属性,对象初始化程序和集合初始化程序。
某些LINQ功能使用新3.5程序集中的类,接口,委托和扩展方法(例如System.Core.dll)。重新分发这些程序集违反了许可证,但是可以重新实现它们。使用扩展方法只需要声明一个空的System.Runtime.CompilerServices.ExtensionAttribute
。 LINQ to Objects依赖于IEnumerable <T>扩展和几个委托声明(Action <T>和Func <T>系列),并已在LINQBridge中实现(如mausch所述)。 LINQ to XML和LINQ to DataSets依靠LINQ to Objects,我想也可以在.Net 2.0中实现,但是我还没有看到这样做。
LINQ to SQL和LINQ to Entities需要许多新类(DataContext / ObjectContext,许多属性,EntitySet <T>,EntityRef <T>,Link <T>,IQueryable <T> (等)和表达式树,即使以某种方式重新实现了它们,也可能至少需要.Net 2.0 SP1才能正常工作。