Problème avec la conversion de int en string dans Linq en 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? Note, que dans VB.NET il n'y a aucun problème d'utiliser le premier morceau il fonctionne tout simplement Grand, VB est flexible, Je ne peux pas s'habituer à C#'S rigueur!!!
16 réponses
avec EF v4 vous pouvez utiliser SqlFunctions.StringConvert
. Il n'y a pas de surcharge pour int donc vous devez mouler à un double ou une décimale. 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 de la chaîne 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 });
}
utiliser LinqToObject : contacts. AsEnumerable ()
var items = from c in contacts.AsEnumerable()
select new ListItem
{
Value = c.ContactId.ToString(),
Text = c.Name
};
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();
}
}
Sqlfonctions.StringConvert fonctionnera, mais je le trouve encombrant, et la plupart du temps, je n'ai pas vraiment besoin d'effectuer la conversion de chaîne du côté SQL.
ce que je fais si je veux faire des manipulations de chaînes, c'est effectuer la requête dans linq-to-entities d'abord, puis manipuler les piqûres dans linq-to-objects. Dans cet exemple, je veux obtenir un ensemble de données contenant le nom complet d'un Contact, et ContactLocationKey, qui est la concatination de chaîne de deux entiers colonnes (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 devient encombrant d'avoir à écrire deux sélections anonymes, mais je dirais que cela est compensé par la commodité dont vous pouvez effectuer des chaînes (et d'autres) fonctions non supportées dans L2E. Gardez également à l'esprit qu'il y a probablement une pénalité de performance en utilisant cette méthode.
var selectList = db.NewsClasses.ToList<NewsClass>().Select(a => new SelectListItem({
Text = a.ClassName,
Value = a.ClassId.ToString()
});
tout d'abord, convertissez-vous en objet, puis toString() sera correct.
j'ai rencontré ce même problème lorsque j'ai converti mon application MVC2 en MVC3 et juste pour donner une autre solution (propre) à ce problème, je veux poster ce que j'ai fait...
IEnumerable<SelectListItem> producers = new SelectList(Services.GetProducers(),
"ID", "Name", model.ProducerID);
GetProducers() retourne simplement un ensemble de producteurs. P. S. Le SqlFunctions.StringConvert ne marchait pas pour moi.
si votre" contact " agit comme liste générique, j'espère que le code suivant fonctionne bien.
var items = contact.Distinct().OrderBy(c => c.Name)
.Select( c => new ListItem
{
Value = c.ContactId.ToString(),
Text = c.Name
});
Merci.
la réponse de Brian Cauthon est excellente! Juste une petite mise à jour, pour EF 6, la classe a été déplacée dans un autre espace de noms. Ainsi, avant L'EF 6, Vous devez 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 compilera très bien mais lancera une erreur d'exécution. J'espère que cette remarque permet d'éviter une certaine confusion.
en utilisant MySql, le SqlFunctions.StringConvert
ne fonctionnait pas pour moi. Comme j'utilise SelectListItem
dans plus de 20 endroits dans mon projet, je voulais une solution qui fonctionne sans contorsionner les instructions 20+ LINQ. Ma solution était de sous-classe SelectedListItem
afin de fournir un setter entier, qui déplace la conversion de type loin de LINQ. Évidemment, cette solution est difficile à généraliser, mais elle a été très utile pour mon projet spécifique.
pour utiliser, créer le type et l'utilisation votre requête LINQ à la place de SelectedListItem
et utiliser IntValue à la place de la valeur.
public class BtoSelectedListItem : SelectListItem
{
public int IntValue
{
get { return string.IsNullOrEmpty(Value) ? 0 : int.Parse(Value); }
set { Value = value.ToString(); }
}
}
une solution de plus:
c.ContactId + ""
il suffit d'ajouter une chaîne vide et elle sera convertie en chaîne.
si vous utilisez entity framework et que vous voulez rendre le seul int acceptable, alors vous pouvez l'utiliser dans linq query vous pouvez essayer ceci
var items = from c in contacts
select new ListItem
{
Value = (int)ContractId
Text = c.Name
};
cela fonctionnera parce que l'utilisation de (int) jettera votre valeur à l'int de sorte que vous n'avez pas besoin de conversion pour la chaîne en int et vous obtenez le résultat que vous voulez.
cela a fonctionné pour moi dans mon projet, je pense qu'il serait utile pour vous
la manière la plus simple:
var items = from c in contacts
select new ListItem
{
Value = c.ContactId + "",
Text = c.Name
};
ma compréhension est que vous devez créer une classe partielle pour" étendre " votre modèle et ajouter une propriété qui est en lecture seule qui peut utiliser le reste des propriétés de la classe.
public partial class Contact{
public string ContactIdString
{
get{
return this.ContactId.ToString();
}
}
}
puis
var items = from c in contacts
select new ListItem
{
Value = c.ContactIdString,
Text = c.Name
};
var items = from c in contacts
select new ListItem
{
Value = String.Concat(c.ContactId), //This Works in Linq to Entity!
Text = c.Name
};
j'ai trouvé que SqlFunctions.StringConvert((double)c.Age)
ne marchait pas pour moi non plus le champ est de type Nullable<Int32>
m'a demandé beaucoup de recherches au cours des derniers jours d'essais et d'erreurs pour trouver ceci.
j'espère que cela aidera quelques codeurs là-bas.
pouvez-vous essayer:
var items = from c in contacts
select new ListItem
{
Value = Convert.ToString(c.ContactId),
Text = c.Name
};