views:

433

answers:

4

Hi,

What is difference between these two statements:

 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;

and

 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);

Is there any performance related issue in these statements. (For simplicity c contains only these 3 coloums.)

Thanks.

A: 

If in doubt, profile.

But yes, I think that there is a performance overhead. If you do select c then the collection will contain references to the original items. If you do select new { ... } then C# is building an anonymous type for you, creating new instances of that type and filling them with data. Sounds definitely slower to me.

Joey
+2  A: 

The main difference is that the first example returns references to existing instances while the second example creates new instances of an anonymous type. I would be more concerned with this issue than any possible performance issues.

Brian Rasmussen
+8  A: 

What is difference between these two statements

The first returns a filtered sequence of the original/complete source object; the second still does the filter, but returns a sequence of an anonymous type with just those three properties.

Is there any performance related issue in these statements

Performance depends on the back-end. If this is LINQ-to-Objects, then with new {...} you are creating extra objects (anonymous types) per record, so there may be a very small overhead. However, if this is LINQ-to-SQL etc (a database back-end), then this can be a huge benefit. The query builder will check which columns are needed, and will only fetch the three in your anon-type; if you have (for example) a BLOB (or just long varchar) in your data that you don't need, this can be a huge benefit.

Additional notes: you can't include anonymous types in the signature of a method, so you might find you need to declare your own DTO type for this purpose:

return new CustomerDto { Company = c.Company, Entered = c.Entered, PK = c.pk};
...
public class CustomerDto { ... }
Marc Gravell
+1 for the generic answer, but in his situation he is returning all of the columns anyway.
ck
Yes ck is correct i am returning all the columns.
Waheed
+2  A: 

I ran some tests (using Stopwatch). In no cases were anonymous types faster, in Linq-to-SQL (against SQL Server), Linq-to-Entities (against MySQL), and Linq-to-Objects (against a List). In fact, usually it was slower, depending on how many columns you select.

One of my results: I ran each query 5000 times against a 5-column table populated by 400 rows with Linq-to-Entities.

anonymous object (selecting 1 column): 17314ms

anonymous object (selecting 5 columns): 19193ms

source object: 16055ms

Anyway, the best way to find out is to test it yourself (takes about the time to write a good post).

Alex