Problema al convertir int a cadena en Linq a entidades
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
};
¿Hay alguna forma de que pueda lograr esto? Tenga en cuenta que en VB.NET no hay problema al usar el primer fragmento, funciona muy bien, VB es flexible, ¡no puedo acostumbrarme al rigor de C#!
Con EF v4 puedes usar SqlFunctions.StringConvert
. No hay sobrecarga para int, por lo que es necesario realizar la conversión a doble o decimal. Tu código termina luciendo así:
var items = from c in contacts
select new ListItem
{
Value = SqlFunctions.StringConvert((double)c.ContactId).Trim(),
Text = c.Name
};
Resolví un problema similar colocando la conversión del número entero a cadena fuera de la consulta. Esto se puede lograr colocando la consulta en un objeto.
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 });
}
Utilice LinqToObject: contactos. ComoEnumerable()
var items = from c in contacts.AsEnumerable()
select new ListItem
{
Value = c.ContactId.ToString(),
Text = c.Name
};
SqlFunctions.StringConvert funcionará, pero lo encuentro engorroso y, la mayoría de las veces, no tengo una necesidad real de realizar la conversión de cadenas en el lado SQL.
Lo que hago si quiero manipular cadenas es realizar primero la consulta en linq-to-entities y luego manipular las picaduras en linq-to-objects. En este ejemplo, quiero obtener un conjunto de datos que contiene el nombre completo de un contacto y ContactLocationKey, que es la concatenación de cadenas de dos columnas de números enteros (ContactID y 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();
Ahora, admito que resulta engorroso tener que escribir dos selecciones anónimas, pero yo diría que eso se ve superado por la conveniencia de poder realizar funciones de cadena (y otras) que no son compatibles con L2E. También tenga en cuenta que probablemente haya una penalización en el rendimiento al utilizar este método.
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();
}
}