¿Cómo convierto correctamente dos columnas de SQL (2008) usando Linq en un diccionario (para almacenamiento en caché)?
Actualmente recorro el IQueryable b / c No puedo hacer que funcione el método ToDictionary. ¿Algunas ideas? 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 obtengo este error: No se puede convertir de 'System.Linq.IQueryable' a 'System.Collections.Generic.IEnumerable'
c#
linq
linq-to-sql
Codewerks
fuente
fuente
kvp => kvp.Value as string
. El punto de la respuesta fue.AsEnumerable()
.AsEnumerable
necesario? Para mí también funciona sin eso, pero probablemente Linq ya haya cambiado (han pasado 7 años)AsEnumerable
era necesario. No recuerdo exactamente por qué, después de todo este tiempo, pero una posible explicación es queToDictionary
era un método de extensión activadoIEnumerable
, pero la interfaz para Linq-to-SQL noIEnumerable
.Solo está definiendo la clave, pero también debe incluir el valor:
var dic = (from p in db.Table select new {p.Key, p.Value }) .ToDictionary(p => p.Key, p=> p.Value);
fuente
<string, string>
pieza hace que utilice lapublic static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer);
sobrecarga en lugar de lapublic static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector);
sobrecarga..AsEnumerable()
antes.ToDictionary()
Gracias chicos, sus respuestas me ayudaron a solucionar este problema, deberían ser:
var dic = db .Table .Select(p => new { p.Key, p.Value }) .AsEnumerable() .ToDictionary(k=> k.Key, v => v.Value);
fuente
¿Por qué crearía un objeto anónimo para cada elemento de la tabla solo para convertirlo?
Simplemente podría usar algo como:
IDictionary<string, string> dic = db.Table.ToDictionary(row => row.Key, row => row.Value);
Es posible que deba incluir una llamada AsEnumerable () entre Table y ToDictionary (). No sé el tipo exacto de db.Table.También corrija la primera muestra, su segunda variable de ciclo no coincide en la declaración y el uso.
fuente
ToDictionary
está en memoria. No crear un objeto anónimo significa que todas las columnas se recuperan de la base de datos en lugar de solo las que necesita.ToDictionary
no conoce la estructura subyacente, solo llama a las dos devoluciones de llamada para la clave y el valor (en este caso, la propiedad simple seleccionando lambdas), por lo que estaToDictionary
llamada debería ser funcionalmente equivalente al foreach en el ejemplo que proporcionó. Hasta donde yo sé, todos los métodos LINQ son diferidos, lo que significa que las devoluciones de llamada solo se llaman cuando es necesario.