这两个陈述之间有什么区别:
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。)
感谢。
答案 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#正在为你构建一个匿名类型,创建该类型的新实例并用数据填充它们。听起来对我来说肯定慢了。