Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

linq: Does ToDictionary cut down the number of columns returned?

Tags:

c#

linq

I have a simple Linq query:

var dict = (from i in Customers select i).ToDictionary(i => i.Id1, i => i.Id2);

Does Linq2sql know to cut down the select to two fields (Id1, Id2) although the query says select i?

like image 569
Candy Chiu Avatar asked Dec 06 '22 08:12

Candy Chiu


2 Answers

No. The Queryable class which things like LINQ to SQL rely on doesn't contain a declaration for ToDictionary (and there are no other classes with suitable extension methods) so it ends up using the implementation in Enumerable - i.e. LINQ to Objects. That uses a plain delegate rather than an expression tree, so there's really no sensible way it could work out what's required.

To make the query more efficient, use an anonymous type to capture everything you're going to need in the Select part:

var dict = db.Customers
             // Here i is a full Customer, logically...
             .Select(i => new { i.Id1, i.Id2 })
             // But here p is just the pair of Id1, Id2
             .ToDictionary(p => p.Id1, p => p.Id2);

Another alternative would be to do this as an extension method yourself - it should be possible to write an overload of ToDictionary taking two expression trees (and the query so far), and combine them into a new expression tree to create a key/value pair, then pass that to Select, then calling the normal ToDictionary afterwards. It's probably not worth the hassle if you're only doing this once, but if you're doing it in multiple places it could be useful.

like image 139
Jon Skeet Avatar answered Dec 14 '22 22:12

Jon Skeet


No LINQToSQL cannot know to cut down the Select for you. You need use an anonymous type. See below.

var dict = (from customer in Customers select new { customer.Id1, customer.Id2 })
           .ToDictionary(d => d.Id1, d => d.Id2);
like image 37
Sam Leach Avatar answered Dec 15 '22 00:12

Sam Leach