我对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;
我可以区分的是速度方面的性能差异,即第二次查询将比第一次查询花费更多时间执行。
它们之间是否存在其他“差异”或“更好用”概念?
答案 0 :(得分:30)
使用new
关键字,他们正在构建一个只包含这四个字段的匿名对象。也许Orders有1000个字段,它们只需要4个字段。
如果您在LINQ-to-SQL或Entity Framework(或其他类似的ORM)中执行此操作,它将构建并发送到SQL Server的SELECT
将仅加载这4个字段(请注意,NHibernate不会完全支持db级别的预测。当你加载一个实体时,你必须完全加载它。在网络上传输的数据较少并且此数据包含在索引中的可能性很小(从索引加载数据通常比从表中加载数据更快,因为该表可能有1000个字段,而索引可以包含这些数据4字段)。
在SQL术语中仅选择某些列的操作称为PROJECTION
。
具体案例:假设你在SQL之上构建一个文件系统。字段是:
现在您要阅读文件列表。 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)
,binary
或xml
数据类型),我们可能希望从查询中排除这些数据类型。
如果您要select o
,那么您将选择Order
及其所有属性和行为。