¿Cómo puedo convertir correctamente dos columnas de SQL (2008) el uso de Linq en un Diccionario (para el almacenamiento en caché)?

Yo actualmente bucle a través de la IQueryable < t > b/c no puedo obtener el ToDictionary método de trabajo. Alguna idea?
Esto funciona:

var query = from p in db.Table
            select p;

Dictionary<string, string> dic = new Dictionary<string, string>();

foreach (var p in query)
{
    dic.Add(sub.Key, sub.Value);
}

Lo que realmente me gustaría hacer es algo como esto, que no parece funcionar:

var dic = (from p in db.Table
             select new {p.Key, p.Value })
            .ToDictionary<string, string>(p => p.Key);

Pero me sale este error:
No se puede convertir de Sistema.Linq.IQueryable < t > ‘ a ‘del Sistema.Las colecciones.Genérica.IEnumerable’

InformationsquelleAutor Codewerks | 2008-10-28

4 Comentarios

  1. 116
    var dictionary = db
        .Table
        .Select(p => new { p.Key, p.Value })
        .AsEnumerable()
        .ToDictionary(kvp => kvp.Key, kvp => kvp.Value)
    ;
    • Lo siento, puede que no haya sido claro, he tratado de thie antes, pero esto crea un Diccionario<cadena, #Tipo Anónimo>, no Dictionary<string, string>
    • Trate de kvp => kvp.Value as string. El punto de la respuesta fue .AsEnumerable().
    • Gracias, sí me imaginé AsEnumerable era necesario, pero la ToDictionary llamada todavía no funciona. Ambas columnas se varchars en SQL, por lo que se vuelven como las cadenas, pero no puedo averiguar cómo llegar a meter en un Dic….
    • figued un vistazo, gracias por su ayuda!
    • No sé si esto es todavía relevante, pero ¿por qué el AsEnumerable necesario? Para mí funciona sin que demasiado, pero probablemente Linq ya ha cambiado (7 años han pasado)
    • En el momento, el AsEnumerable era necesario. No recuerdo exactamente por qué, después de todo este tiempo, pero una posible explicación es que ToDictionary fue un método de extensión en IEnumerable, pero la interfaz de Linq to SQL no era IEnumerable.

  2. 14

    Para definir la clave, pero es necesario incluir el valor también:

    var dic = (from p in db.Table
                 select new {p.Key, p.Value })
                .ToDictionary(p => p.Key, p=> p.Value);
    • publicar la corrección para el resto de nosotros por favor
    • -1 El error es que la <string, string> parte hace uso de la public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer); sobrecarga en lugar de la public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector); de sobrecarga.
    • Creo que todavía necesita .AsEnumerable() antes de .ToDictionary()
    • funcionó a la perfección … por último en el que yo estaba buscando
  3. 9

    Muchas gracias a todos, sus respuestas me ayudaron a solucionar este problema, debe ser:

    var dic = db
            .Table
            .Select(p => new { p.Key, p.Value })
            .AsEnumerable()
            .ToDictionary(k=> k.Key, v => v.Value);
    • La razón que usted necesita AsEnumerable() es porque LINQ to SQL no se mezcla local y remoto (SQL), procesamiento, para esto hace que la primera parte para ejecutar en el servidor SQL server y, a continuación, la final de la parte posterior para ejecutar de forma local utilizando LINQ to Objects que puede hacer Dictionarys 🙂
    • Hace sentido. También, el segundo parámetro en ToDictionary necesita su propio Func argumentos, que fue de disparo me anteriores.
  4. 1

    ¿Por qué crear un objeto anónimo para cada elemento en la tabla sólo para convertirlo?

    Usted podría simplemente usar algo como:
    IDictionary<string, string> dic = db.Table.ToDictionary(row => row.Key, row => row.Value);
    Puede ser necesario incluir un AsEnumerable() la llamada entre la Tabla y ToDictionary().
    No sé el tipo exacto de db.Tabla.


    Corregir también la primera muestra, la segunda variable de bucle es el desajuste en la declaración y uso.

    • Porque ToDictionary es en memoria. No crear un objeto anónimo significa que todas las columnas se recuperan de la base de datos en lugar de sólo los que necesita.
    • ToDictionary no sabe acerca de la estructura subyacente, llama a los dos devoluciones de llamada de clave y valor (en este caso de propiedad simple selección de las lambdas), por lo que este ToDictionary llamada debe ser funcionalmente equivalente a la foreach en el ejemplo que él proporcionó. Que yo sepa todos los de LINQ métodos son diferidos, lo que significa que los callbacks son solo llama cuando es necesario.
    • Si usted mira con SQL Server Profiler, verás que con un objeto anónimo sólo dos columnas seleccionadas, y sin ella, todas las columnas seleccionadas.

Dejar respuesta

Please enter your comment!
Please enter your name here