211 votes

Problème de conversion d'int en string dans Linq to entities

var items = from c in contacts
            select new ListItem
            {
                Value = c.ContactId, //Cannot implicitly convert type 'int' (ContactId) to 'string' (Value).
                Text = c.Name
            };
var items = from c in contacts
            select new ListItem
            {
                Value = c.ContactId.ToString(), //Throws exception: ToString is not supported in linq to entities.
                Text = c.Name
            };

Y a-t-il un moyen d'y parvenir ? Notez que dans VB.NET il n'y a pas de problème, utilisez le premier extrait, il fonctionne parfaitement, VB est flexible, je n'arrive pas à m'habituer à la rigueur de C# !

2 votes

.ToString() ne fonctionne pas non plus pour LinqToEF en VB. IMHO, un peu stupide.

5 votes

@StingyJack, le problème vient de l'ELINQ (entités linq 2), parce qu'il traduit votre code en SQL, et quand il s'agit d'une requête ToString interne, il ne sait pas comment traduire 'ToString' en SQL. Contrairement à ce qui se passe avec les objets linq 2, lorsqu'il n'y a pas de traduction et que tout est constitué de lambdas CLR, le traitement s'effectue directement sur les objets demandés.

1 votes

Je suis simplement irrité qu'ils autorisent la compilation de ce type d'erreur, et que j'aie dû troller éternellement pour trouver une description en anglais simple de la cause (sans jargon juridique et académique).

321voto

Brian Cauthon Points 4031

Avec EF v4, vous pouvez utiliser SqlFunctions.StringConvert . Il n'y a pas de surcharge pour int, vous devez donc le convertir en un double ou un décimal. Votre code finit par ressembler à ceci :

var items = from c in contacts
            select new ListItem
            {
                Value = SqlFunctions.StringConvert((double)c.ContactId).Trim(),
                Text = c.Name
            };

239 votes

Pourquoi diable n'ont-ils pas inclus une surcharge pour int ?

0 votes

Cela ne fonctionne pas pour moi, l'erreur se transforme en : La méthode spécifiée 'System.String StringConvert(System.Nullable`1[System.Double])' sur le type 'System.Data.Objects.SqlClient.SqlFunctions' ne peut pas être traduite en une expression de magasin LINQ to Entities.

1 votes

Que fait le SqlFunctions.StringConvert à quoi ressemble la partie de votre requête ? D'après l'erreur, on dirait que vous passez un fichier Nullable<double> ( double? ) au lieu d'un double . Essayez d'appeler GetValueOrDefault() avant de le faire entrer.

12voto

jrosseel Points 522

J'ai résolu un problème similaire en plaçant la conversion de l'entier en chaîne hors de la requête. Cela peut être réalisé en plaçant la requête dans un objet.

var items = from c in contacts
            select new 
            {
                Value = c.ContactId,
                Text = c.Name
            };
var itemList = new SelectList();
foreach (var item in items)
{
    itemList.Add(new SelectListItem{ Value = item.ContactId, Text = item.Name });
}

0 votes

C'est une façon de résoudre le problème, mais gardez à l'esprit que cela augmentera le temps d'exécution, si vous avez une grande quantité d'objets, ce foreach est exagéré...

8voto

Shimmy Points 23393

Ça marche :

var collection = contacts.ToDictionary(i=> i.ContactId, i=> i.Name);
IEnumerable<ListItem> listItems = from i in collection
                                  select new ListItem
                                  {
                                      Value = Key.ToString(),
                                      Text = Value
                                  };

Ou le faire en ligne :

IEnumerable<ListItem> listItems = 
    from i in contacts.ToDictionary(i=> i.ContactId, i=> i.Name)
                                  select new ListItem
                                  {
                                      Value = Key.ToString(),
                                      Text = Value
                                  };

8voto

Mohammadreza Points 435

Utiliser LinqToObject : contacts. AsEnumerable()

var items = from c in contacts.AsEnumerable()
            select new ListItem
            {
                Value = c.ContactId.ToString(),
                Text = c.Name
            };

0 votes

Merci. Pour info, j'essaie de résoudre un problème légèrement différent. J'utilise LINQ to entities / lambda et cela fonctionne. J'essayais de convertir un Int en String et d'utiliser "Contains" pour trouver les résultats correspondants --> ie db.contacts.AsEnumerable().Where(c => c.ContactId.ToString().Contains( Chercher un élément )).ToList() ; ;

11 votes

Si vous appelez AsEnumerable vous paierez un prix élevé en termes de performances sur les bases de données plus importantes, car il apportera tout en mémoire. IEnumerable est plus lent par rapport à IQueryable car ce dernier est exécuté exclusivement dans la base de données.

4voto

Nestor Points 872
public static IEnumerable<SelectListItem> GetCustomerList()
        {
            using (SiteDataContext db = new SiteDataContext())
            {
                var list = from l in db.Customers.AsEnumerable()
                           orderby l.CompanyName
                           select new SelectListItem { Value = l.CustomerID.ToString(), Text = l.CompanyName };

                return list.ToList();
            }
        }

0 votes

L'avez-vous testé et cela fonctionne-t-il ? lire ce réponse avant.

0 votes

Oui, je l'utilise déjà. Il fonctionne pour MVC3, EF4, CTP5, SQL CE4.

0 votes

Cela semble plus élégant que de transformer la boîte en double et d'utiliser le StringConvert.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X