.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<T>
)
LINQ to SQL/Entities:否 (IQueryable<T>
)
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<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 才能工作。
【讨论】:
【参考方案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 应用程序吗?