.NET 2.0 运行时上的 LINQ

Posted

技术标签:

【中文标题】.NET 2.0 运行时上的 LINQ【英文标题】:LINQ on the .NET 2.0 Runtime 【发布时间】:2010-09-05 08:28:32 【问题描述】:

启用 LINQ 的应用能否在仅安装了 .NET 2.0 运行时的机器上运行?

理论上,LINQ 只不过是语法糖,生成的 IL 代码应该与 .NET 2.0 中的代码相同。

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

【问题讨论】:

【参考方案1】:

奇怪的是没有人提到LINQBridge。这个很棒的小项目是将 LINQ(IEnumerable,但没有 IQueryable)及其依赖项(Func、Action 等)向后移植到 .NET 2.0。并且:

如果您的项目引用 LINQBridge 在编译期间,它将绑定 到 LINQBridge 的查询运算符;如果它 期间引用 System.Core 编译,然后它将绑定到 Framework 3.5 的查询运算符。

【讨论】:

+1 我经常使用这个。注意:这是 LINQ to Objects(IEnumerable 扩展)的实现,如果使用 VS2008 (C# 3.0) 目标框架 2.0+,则可以完美运行。它不是 LINQ to SQL 或其他 LINQ 提供程序的实现。 很遗憾 LINQBridge 不支持 Linq-2-Xml :( Linq-2-Xml 使得使用 Xml 变得简单而美好。 @Dmitry Linq2Xml 是我如此快速完成工作的方式。 Xpath 仍然是一个不错的选择,但不够流畅。 我刚刚遇到了同一作者的 BackLinq raboof.com/projects/backlinq!有谁知道有什么区别或最新的? @Quandary :Func、Action 和“LINQ to objects”本身就非常有用。就我个人而言,我比 IQueryables 更多地使用它们。【参考方案2】:

有一些“黑客”涉及使用 3.5 框架中的 System.Core.dll 使其与 .net 2.0 一起运行,但我个人不希望使用这种有点不稳定的基础。

请看这里:LINQ support on .NET 2.0

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

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

【讨论】:

重新分发 System.Core.dll 违反了微软的许可 我编译运行后,bin文件夹中除了debug文件夹什么都没有。 :( 我正在 .Net 4.0 Visual Studio 2010 中构建控制台应用程序。 @JonasT 如果您使用的是 .net 4.0,那么这根本不适用于您,因为它是关于使用 LINQ 的 .net 2.0。随意提出一个单独的问题,提供有关您的设置的详细信息。 谢谢迈克尔。我正在寻找的只是输出文件。我正在使用.net 2.0。问题是我使用的是 Visual Studio 2010,它不会在 bin 文件夹中产生任何输出。无论如何我可以下载这些输出吗? 许可和专利违反常识。不知道它起源于微软。所有这些都是建立在先前发明的肩膀上的。一切都属于每个人,我希望有一天它会变得显而易见。思维的转变是必须的,否则我们就无法做到人性化。【参考方案3】:

理论上是的,只要您分发 LINQ 特定程序集和任何依赖项。然而,这违反了微软的许可。 Scott Hanselman 写了一篇关于 Deploying ASP.NET MVC on ASP.NET 2.0 的博客文章,这与您想要做的事情相似。

【讨论】:

【参考方案4】:

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

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

这里有人做过:LINQ for .NET 2.0

【讨论】:

【参考方案5】:

简答:

LINQ to Objects:是的 (IEnumerable&lt;T&gt;) LINQ to SQL/Entities:否 (IQueryable&lt;T&gt;) LINQ to XML/DataSets:还没有?

请参阅this question,了解 .Net 3.5 功能在从 VS2008 面向 .Net 2.0 时自动或轻松可用的功能。

基本上,任何只是“语法糖”和新编译器(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&lt;T&gt; 扩展和几个委托声明(Action&lt;T&gt;Func&lt;T&gt; 系列),并已在LINQBridge 中实现(如mausch 所述)。 LINQ to XML 和 LINQ to DataSets 依赖于 LINQ to Objects,我猜这也可以在 .Net 2.0 中实现,但我还没有看到这样做。

LINQ to SQL 和 LINQ to Entities 需要许多新类(DataContext/ObjectContext、大量属性、EntitySet&lt;T&gt;EntityRef&lt;T&gt;Link&lt;T&gt;IQueryable&lt;T&gt; 等)和表达式树,这,即使以某种方式重新实现,也可能至少需要 .Net 2.0 SP1 才能工作。

【讨论】:

【参考方案6】:

我不确定 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 to 对象版本。一切都很简单。

如果你想使用 LINQ,那么事情会有点困难。

【讨论】:

+1,但请注意表达式树(用于 IQueryable)仅在 3.5+ 中可用 .. 是的,你所说的关于 VB 9.0 的一切都适用于 C# 3.0(使用新的编译器,但针对旧的 fx 版本) 但是如果你愿意,你可以编写自己的表达式树实现。【参考方案7】:

不,因为虽然您认为 LINQ 实际上只是语法糖,但它实际上大量使用了表达式树——.NET 2.0 中没有这个功能。

也就是说 .NET 3.5 只是建立在 .NET 2.0 之上,这就是 IL 看起来没有“不同”或“特殊”的原因。

我看不出为什么您不应该只安装 .NET 3.5 Framework。 .NET 2.0 的所有东西都可以正常工作,保证 :)

【讨论】:

.Net 3.0 或更高版本无法安装在 Windows 2000 上。 注意:表达式树由 IQueryable 使用(如在 LINQ to SQL 中),但不被 IEnumerbale 使用(如在 LINQ to Objects 中) 另外,在“企业”世界中,我们确实有一些机器尚未“升级”到.NET 2.0。是的。说真的,我们做到了。 Windows XP 需要 SP3 才能安装 .NET 3.0 或更高版本,并且某些运行 Windows XP Embedded 的设备更新起来并不那么简单。【参考方案8】:

据我所知,LINQ 库仅在框架 3.0 之后才可用。 如果你想在 framework 2.0 中使用类似的东西,你需要自己重写它:) 或者找一个类似的第三方库。我只找到了一点信息here,但也没有说服我。

【讨论】:

以上是关于.NET 2.0 运行时上的 LINQ的主要内容,如果未能解决你的问题,请参考以下文章

将 .NET 3.5 库与应用程序捆绑在一起,因此它可以在仅安装 .NET 2.0 的机器上运行?

.NET 5 Runtime 可以运行 .NET 3.1 应用程序吗?

Windows 容器在 Rancher 上的发展

Windows Server 2008 R2 上的 .NET 2.0 Web 服务未找到模块异常

在 .NET 7上使用 WASM 和 WASI

.net core 2.0 在 ubuntu 上运行控制台应用程序时出错