为什么在LINQ中使用“select new”

时间:2011-09-04 05:48:53

标签: c# .net linq linq-to-sql

我对LINQ to SQL很新,所以请原谅我,如果它是一个外行问题。

我在许多地方看到我们在查询中使用"select new"关键字。 例如,

var orders =  from o in db.Orders select new {
                o.OrderID,
                 o.CustomerID,
                 o.EmployeeID,
                 o.ShippedDate
           }

为什么我们不删除select new,只使用"select o"

var orders =  from o in db.Orders select o;

我可以区分的是速度方面的性能差异,即第二次查询将比第一次查询花费更多时间执行。

它们之间是否存在其他“差异”或“更好用”概念?

3 个答案:

答案 0 :(得分:30)

使用new关键字,他们正在构建一个只包含这四个字段的匿名对象。也许Orders有1000个字段,它们只需要4个字段。

如果您在LINQ-to-SQL或Entity Framework(或其他类似的ORM)中执行此操作,它将构建并发送到SQL Server的SELECT将仅加载这4个字段(请注意,NHibernate不会完全支持db级别的预测。当你加载一个实体时,你必须完全加载它。在网络上传输的数据较少并且此数据包含在索引中的可能性很小(从索引加载数据通常比从表中加载数据更快,因为该表可能有1000个字段,而索引可以包含这些数据4字段)。

在SQL术语中仅选择某些列的操作称为PROJECTION

具体案例:假设你在SQL之上构建一个文件系统。字段是:

  • filename VARCHAR(100)
  • 数据BLOB

现在您要阅读文件列表。 SQL中的简单SELECT filename FROM files。当您只需要data时,为每个文件加载filename将毫无用处。请记住,data部分可以“加权”兆字节,而filename部分最多可以包含100个字符。

在阅读了new使用匿名对象的“乐趣”之后,请记住阅读@pleun写的内容,并记住:ORM就像冰山一样:他们工作的7/8隐藏在下面表面,准备咬你回来。

答案 1 :(得分:14)

给出的答案很好,但我想补充另一个方面。

因为使用select new { },你断开了与datacontext的连接,这使你松开了Linq-to-Sql的变更跟踪机制

因此,仅显示数据,它很好,将导致性能提升。

但是如果你想做更新,那就不行了。

答案 2 :(得分:2)

select new中,我们正在创建一个只包含您需要的属性的新匿名类型。他们都会从匹配的订单中获取属性名称和值。当您不想从源中撤回所有属性时,这很有用。有些可能很大(考虑varchar(max)binaryxml数据类型),我们可能希望从查询中排除这些数据类型。

如果您要select o,那么您将选择Order及其所有属性和行为。