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 de faire cela? Notez que dans VB.NET il n'y a pas de problème, utilisez le premier extrait qui fonctionne à merveille, VB est flexible, je ne parviens pas à m'habituer à la rigueur de C # !!!
Avec EF v4, vous pouvez utiliser SqlFunctions.StringConvert
. Il n'y a pas de surcharge pour int, vous devez donc utiliser un double ou un nombre 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
};
_
J'ai résolu un problème similaire en plaçant la conversion de l'entier en chaîne en dehors de la requête. Ceci peut être réalisé en mettant 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 });
}
Utilisez LinqToObject: contacts .AsEnumerable ()
var items = from c in contacts.AsEnumerable()
select new ListItem
{
Value = c.ContactId.ToString(),
Text = c.Name
};
SqlFunctions.StringConvert fonctionnera, mais je trouve cela fastidieux et, la plupart du temps, je n'ai pas réellement besoin d'effectuer la conversion de chaîne du côté SQL.
Ce que je fais si je veux faire des manipulations de chaîne, c'est d'abord exécuter la requête dans linq-to-entity, puis manipuler les commandes dans linq-to-objects. Dans cet exemple, je souhaite obtenir un ensemble de données contenant le nom complet d'un contact, ainsi que ContactLocationKey, qui est la concaturation de chaîne de deux colonnes de type Integer (ContactID et LocationID).
// perform the linq-to-entities query, query execution is triggered by ToArray()
var data =
(from c in Context.Contacts
select new {
c.ContactID,
c.FullName,
c.LocationID
}).ToArray();
// at this point, the database has been called and we are working in
// linq-to-objects where ToString() is supported
// Key2 is an extra example that wouldn't work in linq-to-entities
var data2 =
(from c in data
select new {
c.FullName,
ContactLocationKey = c.ContactID.ToString() + "." + c.LocationID.ToString(),
Key2 = string.Join(".", c.ContactID.ToString(), c.LocationID.ToString())
}).ToArray();
Maintenant, je reconnais qu’il est fastidieux d’écrire deux sélections anonymes, mais j’arguerais que c’est plus pratique que de pouvoir utiliser des fonctions de chaîne (et d’autres) non prises en charge dans L2E. N'oubliez pas non plus que cette méthode entraîne probablement une baisse des performances.
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();
}
}
var selectList = db.NewsClasses.ToList<NewsClass>().Select(a => new SelectListItem({
Text = a.ClassName,
Value = a.ClassId.ToString()
});
Tout d’abord, convertissez en objet, puis toString () sera correct.
La réponse de Brian Cauthon est excellente! Juste une petite mise à jour, pour EF 6, la classe a été déplacée vers un autre espace de noms. Donc, avant EF 6, vous devriez inclure:
System.Data.Objects.SqlClient
Si vous mettez à jour vers EF 6, ou utilisez simplement cette version, incluez:
System.Data.Entity.SqlServer
En incluant l'espace de noms incorrect avec EF6, le code se compilera parfaitement mais générera une erreur d'exécution. J'espère que cette note aidera à éviter une certaine confusion.
Si votre "contact" agit comme une liste générique, j'espère que le code suivant fonctionnera bien.
var items = contact.Distinct().OrderBy(c => c.Name)
.Select( c => new ListItem
{
Value = c.ContactId.ToString(),
Text = c.Name
});
Merci.
J'ai rencontré ce même problème lorsque je convertissais mon application MVC 2 en MVC 3 et juste pour donner une autre solution (propre) à ce problème, je souhaite publier ce que j'ai fait ...
IEnumerable<SelectListItem> producers = new SelectList(Services.GetProducers(),
"ID", "Name", model.ProducerID);
GetProducers () renvoie simplement une collection d'entités de producteurs. P.S. Le SqlFunctions.StringConvert n'a pas fonctionné pour moi.
Une autre solution:
c.ContactId + ""
Ajoutez simplement une chaîne vide et il sera converti en chaîne.
si vous utilisez un framework d'entité et que vous voulez rendre le seul int acceptable, alors vous pouvez utiliser ceci dans une requête linq, vous pouvez essayer ceci
var items = from c in contacts
select new ListItem
{
Value = (int)ContractId
Text = c.Name
};
cela fonctionnera car using (int) va transtyper votre valeur sur int, vous n'aurez donc besoin d'aucune conversion pour string en int et vous obtiendrez le résultat souhaité.
cela a fonctionné pour moi dans mon projet, je pense que ce serait utile pour vous
En utilisant MySql, le SqlFunctions.StringConvert
ne fonctionnait pas pour moi. Dans la mesure où j’utilise SelectListItem
dans plus de 20 lieux de mon projet, je souhaitais une solution qui fonctionne sans contourner les 20 instructions LINQ. Ma solution a été de sous-classe SelectedListItem
afin de fournir un séparateur d'entiers, qui éloigne LINQ de la conversion de type. Évidemment, cette solution est difficile à généraliser, mais a été très utile pour mon projet spécifique.
Pour l'utiliser, créez le type suivant et utilisez-le dans votre requête LINQ à la place de SelectedListItem
et utilisez IntValue à la place de Value.
public class BtoSelectedListItem : SelectListItem
{
public int IntValue
{
get { return string.IsNullOrEmpty(Value) ? 0 : int.Parse(Value); }
set { Value = value.ToString(); }
}
}