web-dev-qa-db-fra.com

Projection dans KeyValuePair via EF/Linq

J'essaie de charger une liste de KeyValuePairs à partir d'une requête EF/Linq comme celle-ci: 

return (from o in context.myTable 
select new KeyValuePair<int, string>(o.columnA, o.columnB)).ToList();

Mon problème est que cela entraîne l'erreur 

"Seuls les constructeurs et les initialiseurs sans paramètre sont pris en charge dans LINQ to Entities."

Y a-t-il un moyen facile de contourner cela? Je sais que je pourrais créer une classe personnalisée pour cela au lieu d'utiliser KeyValuePair, mais cela semble être une réinvention de la roue.

32
GrandMasterFlush

Sélectionnez uniquement les colonnes et colonnes de votre table et déplacez le traitement ultérieur en mémoire:

return context.myTable
              .Select(o => new { o.columnA, o.columnB }) // only two fields
              .AsEnumerable() // to clients memory
              .Select(o => new KeyValuePair<int, string>(o.columnA, o.columnB))
              .ToList();

Pensez également à créer un dictionnaire contenant des paires de valeurs clés:

return context.myTable.ToDictionary(o => o.columnA, o => o.columnB).ToList();
62
Sergey Berezovskiy

Étant donné que LINQ to Entities ne prend pas en charge KeyValuePair, vous devez activer LINQ to Object en utilisant AsEnumerable en premier:

return context.myTable
              .AsEnumerable()
              .Select(new KeyValuePair<int, string>(o.columnA, o.columnB))
              .ToList();
9
cuongle

Il existe également une alternative, lorsque vous souhaitez stocker plusieurs valeurs pour une clé, il existe quelque chose qui s'appelle Lookup

Représente une collection de clés mappées chacune à une ou plusieurs valeurs.

Ici vous avez quelques documentations officielles.

De plus, lookup semble être beaucoup plus rapide que Dictionary <TKey, List <TValue>>.

0
Bartosz