LINQ:'选择c'和'选择新(c ......')之间的区别

时间:2009-08-10 10:54:50

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

这两个陈述之间有什么区别:

 var result = from c in context.CustomerEntities
 join p in context.ProjectEntities on c.Pk equals p.CustomerPk
 where p.Entered > DateTime.Now.AddDays(-15)
 select c; 

 var result = from c in context.CustomerEntities
 join p in context.ProjectEntities on c.Pk equals p.CustomerPk
 where p.Entered > DateTime.Now.AddDays(-15)
 select new (c.Company, c.Entered, c.pk);

这些陈述中是否存在与绩效相关的问题。 (为简单起见,c只包含这3个coloums。)

感谢。

4 个答案:

答案 0 :(得分:10)

  

这两个陈述之间有什么区别

第一个返回原始/完整源对象的过滤序列;第二个仍然使用过滤器,但返回一个匿名类型的序列,其中只是这三个属性。

  

这些陈述中是否存在与绩效相关的问题

性能取决于后端。如果这是LINQ-to-Objects,那么使用new {...}每个记录创建额外的对象(匿名类型),因此可能会有非常小的开销。但是,如果这是LINQ-to-SQL等(数据库后端),那么这可能是一个巨大的好处。查询构建器将检查需要哪些列,并且只会获取anon类型中的三列;如果您在数据中有(例如)BLOB(或只是长varchar),那么这可能是巨大的好处。

附加说明:您不能在方法的签名中包含匿名类型,因此您可能会发现需要为此目的声明自己的DTO类型:

return new CustomerDto { Company = c.Company, Entered = c.Entered, PK = c.pk};
...
public class CustomerDto { ... }

答案 1 :(得分:2)

主要区别在于第一个示例返回对现有实例的引用,而第二个示例创建匿名类型的新实例。我会比任何可能的性能问题更关心这个问题。

答案 2 :(得分:2)

我运行了一些测试(使用秒表)。在任何情况下,匿名类型都不会更快,在Linq-to-SQL(针对SQL Server),Linq-to-Entities(针对MySQL)和Linq-to-Objects(针对List)中。实际上,通常它会更慢,具体取决于您选择的列数。

我的一个结果: 我针对5列表运行了每次查询5000次,这些表填充了400行Linq-to-Entities。

匿名对象(选择1列):17314ms

匿名对象(选择5列):19193ms

源对象:16055ms

无论如何,最好的方法是自己测试(花点时间写一篇好文章)。

答案 3 :(得分:1)

如果有疑问,请说明。

但是,我认为存在性能开销。如果您执行select c,则集合将包含对原始项目的引用。如果你select new { ... },那么C#正在为你构建一个匿名类型,创建该类型的新实例并用数据填充它们。听起来对我来说肯定慢了。