2013-04-18 3 views

ответ

7

Queryable No. класс, такие вещи, как LINQ к SQL полагаться на не содержит декларацию для ToDictionary (и нет никаких других классов с подходящим расширением методы), поэтому он заканчивается использованием реализации в Enumerable - т.е. LINQ to Objects. Это использует простой делегат, а не дерево выражений, поэтому нет никакого разумного способа, чтобы мог решить, что требуется.

Чтобы сделать запрос более эффективным, использовать анонимный тип, чтобы захватить все, что вы будете нуждаться в Select части:

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

Другой альтернативой было бы сделать это, как метод расширения себя - это должно быть возможно написать перегрузку ToDictionary с двумя деревьями выражений (и до сих пор) и объединить их в новое дерево выражений для создания пары ключ/значение, затем передать это значение Select, а затем вызвать нормальный ToDictionary. Это, вероятно, не стоит хлопот, если вы делаете это только один раз, но если вы делаете это в нескольких местах, это может быть полезно.

+0

Мне любопытно, не зависит ли TODictionary от реализации поставщика LINQ? Или ToDictionary не является частью LINQ? – rossisdead

+1

@rossisdead: Это часть LINQ to Objects - это не часть Queryable, только Enumerable. –

+0

Gotcha, спасибо! – rossisdead

3

Насколько я знаю, это не так. Он будет неуверенно выполнять ваш запрос и получать все в полях на столе Customers.

Вы могли бы переписать его, чтобы он сделал:

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

Нет LINQToSQL не может знать, чтобы сократить Select для вас. Вам нужно использовать анонимный тип. Смотри ниже.

var dict = (from customer in Customers select new { customer.Id1, customer.Id2 }) 
      .ToDictionary(d => d.Id1, d => d.Id2); 
Смежные вопросы