在.NET 2.0运行时上使用LINQ

61

一个启用了LINQ的应用程序能够在只安装了.NET 2.0运行时的机器上运行吗?

从理论上讲,LINQ仅仅是一种语法糖,生成的IL代码应该与在.NET 2.0中生成的代码相同。

我如何在不使用.NET 3.5库的情况下编写LINQ?它能在.NET 2.0上运行吗?

8个回答

82
很奇怪没有人提到LINQBridge。这个小巧而强大的项目将LINQ(IEnumerable,但不包括IQueryable)和它的依赖项(如Func, Action等)回溯到.NET 2.0版本。如果你的项目在编译过程中引用了LINQBridge,那么它将绑定到LINQBridge的查询运算符;如果它在编译期间引用了System.Core,则它将绑定到Framework 3.5的查询运算符。

2
+1 我经常使用这个。注意:这是 LINQ to Objects 的实现(IEnumerable 扩展),如果使用 VS2008(C# 3.0)并针对框架 2.0+ 进行目标设置,则可以完美运行。它不是 LINQ to SQL 或其他 LINQ 提供程序的实现。 - Lucas
1
很遗憾,LINQBridge不支持Linq-2-Xml :( Linq-2-Xml使得处理Xml变得简单而美好。 - Dmitrii Lobanov
我刚刚发现了由同一位作者开发的BackLinq http://www.raboof.com/projects/backlinq/!有人知道它们之间的区别或哪一个是最新的吗? - ala
如果它不支持IQueryable(它确实不支持),那还有什么意义??? - Stefan Steiger
1
@Quandary:Func、Action和“LINQ to objects”本身非常有用。就我个人而言,我使用它们的频率比IQueryables高得多。 - Mauricio Scheffer
显示剩余4条评论

34

有一些“技巧”可以使用来自3.5框架的System.Core.dll使其在.net 2.0上运行,但个人不希望使用这种有点不稳定的基础。

请看此处:.NET 2.0上的LINQ支持

  1. 创建新的控制台应用程序
  2. 仅保留System和System.Core作为引用程序集
  3. 将System.Core的复制本地设置为true,因为它在.NET 2.0中不存在
  4. 在Main方法中使用LINQ查询。例如下面的查询。
  5. 构建
  6. 将所有bin输出复制到仅安装了.NET 2.0的机器上
  7. 运行

(需要.net 2.0 SP1,我不知道捆绑System.Core.dll是否违反EULA)


38
重新分发 System.Core.dll 是违反微软许可协议的行为。 - Lucas
构建和运行后,bin文件夹里除了debug文件夹什么也没有。 :( 我正在使用.Net 4.0 Visual Studio 2010构建控制台应用程序。 - Jonas T
@JonasT 如果你使用的是 .net 4.0,那么这个问题并不适用于你,因为它是关于在 .net 2.0 中使用 LINQ 的。请随意提出一个单独的问题,并提供有关您的设置的详细信息。 - Michael Stum
谢谢Michael。我需要的只是输出文件。我正在使用.net 2.0。问题是我正在使用Visual Studio 2010,它不会在bin文件夹中生成任何输出。有没有办法可以下载这些输出文件? - Jonas T
许可证和专利违反常识。没有一个想法是源于微软的。它们都是建立在先前发明的基础上。一切属于每个人,我希望有一天这将变得显而易见。思维方式的转变是必须的,否则我们作为人类就无法成功。 - Mariusz

11

理论上是可以的,只要你分发LINQ特定程序集和任何依赖项。然而,这违反了微软的许可协议。Scott Hanselman撰写了一篇关于在ASP.NET 2.0上部署ASP.NET MVC的博客文章,类似于你所想要做的事情。


7

您可以使用来自Mono(.NET for Linux)的LINQ源代码在.NET 2.0上运行LINQ。

IEnumerable<T> : yes 
IQueryable<T>  : yes
LINQ to XML : has been working in the trunk, but due to further additions, the trunk doesn't compile anymore

这里有人做过类似的事情:
针对 .NET 2.0 的 LINQ


6

简短回答:

  • LINQ to Objects:是的(IEnumerable<T>
  • LINQ to SQL/Entities:不行(IQueryable<T>
  • LINQ to XML/DataSets:还没有确定?

请查看此问题,了解在使用VS2008针对.Net 2.0时自动提供或只需少量努力即可获得的.Net 3.5功能。

基本上,任何仅为“语法糖”的内容以及新编译器(C#3.0,VB 9.0)生成的2.0兼容IL都可以工作。这包括许多LINQ使用的功能,例如匿名类、将lambda用作匿名委托、自动属性、对象初始化程序和集合初始化程序。

一些LINQ功能使用存储在新的3.5程序集(例如System.Core.dll)中的类、接口、委托和扩展方法。重新分发这些程序集是违反许可证的,但它们可以被重新实现。使用扩展方法只需要声明一个空的System.Runtime.CompilerServices.ExtensionAttribute。LINQ to Objects依赖于IEnumerable扩展和几个委托声明(Action和Func系列),并已在LINQBridge(如mausch所提到的)中实现。LINQ to XML和LINQ to DataSets依赖于LINQ to Objects,我想这也可以为.Net 2.0实现,但我还没有看到这样做。
LINQ to SQL和LINQ to Entities需要许多新类(DataContext/ObjectContext,大量属性,EntitySet,EntityRef,Link,IQueryable等)和表达式树,即使以某种方式重新实现,也可能需要至少 .Net 2.0 SP1才能工作。

5

我对C#不是很确定。

然而,我知道只要使用VS 2008编译器针对2.0框架,就可以编写没有3.5库的VB LINQ代码。

但是,你需要自己实现一些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 to objects版本。这都很简单明了。
如果您想使用DLINQ,则会有一些困难。

+1,但请注意,表达式树(用于IQueryable)仅在3.5+版本中可用。 - Lucas
是的,你提到的关于VB 9.0的所有内容同样适用于C# 3.0(使用新编译器但以旧版框架为目标)。 - Lucas
但是如果你愿意的话,你可以编写自己的表达式树实现。 - Scott Wisniewski

3
不,因为虽然你认为LINQ只是语法糖,但它实际上大量使用了表达式树--这是.NET 2.0中缺少的功能。
话虽如此,.NET 3.5只是在.NET 2.0的基础上构建,这就是为什么IL看起来不“不同”或“特殊”的原因。
我不认为你没有理由不安装.NET 3.5 Framework。所有.NET 2.0的内容都可以在其上正常运行,保证 :)

1
.Net 3.0或更高版本无法安装在Windows 2000上。 - Lamar
1
请注意:表达式树被IQueryable使用(如LINQ to SQL),而不被IEnumerable使用(如LINQ to Objects)。 - Lucas
此外,在“企业”世界中,我们实际上有一些机器还没有升级到“.NET 2.0”。是的,我说的很认真。 - cbmeeks
Windows XP需要SP3才能安装.NET 3.0或更高版本,而某些运行Windows XP嵌入式系统的设备更新起来并不那么简单。 - Scott Solmer

2
据我所知,LINQ库只能在框架3.0及以上版本中使用。如果您想在框架2.0中使用类似的功能,您需要自己重写代码或寻找类似的第三方库。我只在这里找到了一些信息,但并没有让我完全信服。请注意保留HTML标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接