6

¡Estoy posteando esto más porque me gustaría aprender más, porque mi trabajo ha sido básicamente evitar el uso de LINQ para Entidades! Aunque sería bueno si pudiera usarlo. Entonces, si alguien me puede aclarar ...LINQ to Entities ToString() - ¿Ninguna de las soluciones propuestas funciona?

Estoy trabajando en una aplicación ASP.Net MVC 3 (la primera) utilizando Entity Framework con código primero como mi modelo de datos. Va a ser una tienda en línea y estoy trabajando en el controlador 'Admin', donde, como administrador, podrá editar productos, etc. Cuando se trata de agregar un nuevo producto, debe especificar una categoría, lo que significa un lista desplegable de categorías.

Comencé devolviendo una colección de categorías IEnumerable en ViewBag, según la información que encontré here. Esta parecía una forma realmente agradable de abordar las cosas.

Pero tengo el mismo error que verá a continuación. Entonces, siguiendo una sugerencia que leí en línea, creé un modelo separado específicamente para crear nuevos productos y editarlos. La colección Categorías se usa para crear una lista desplegable en la vista.

public class ProductModel 
{ 
    public int Id { get; set; } 
    public int CategoryId { get; set; } 
    public string Name { get; set; } 
    public string Description { get; set; } 
    public double Price { get; set; } 
    public bool IsVisible { get; set; } 

    public IEnumerable<SelectListItem> Categories 
    { 
     get 
     { 
      return new DataAccess() 
       .Categories 
       .OrderBy(c => c.Description) 
       .Select(c => new SelectListItem 
        { 
         Value = c.Id.ToString(), 
         Text = c.Description 
        }); 
     } 
    } 
} 

Esto resulta en el mensaje de error: "LINQ to Entities no reconoce el método 'System.String ToString()' método, y este método no puede ser traducido en una expresión tienda.". Una solución en línea propuesta era usar los métodos SqlFunction provistos por Entity Framework. Así que probé este lugar ...

public IEnumerable<SelectListItem> Categories 
    { 
     get 
     { 
      return new DataAccess() 
       .Categories 
       .OrderBy(c => c.Description) 
       .Select(c => new SelectListItem 
        { 
         Value = SqlFunctions.StringConvert((double)c.Id), 
         Text = c.Description 
        }); 
     } 
    } 

Pero esto resulta en este mensaje de error: "El método especificado 'System.String StringConvert (System.Nullable`1 [System.Double])' del tipo ' System.Data.Objects.SqlClient.SqlFunctions 'no se pueden traducir a una expresión de tienda LINQ to Entities ".

Incluso he intentado agregar una propiedad de solo lectura a la clase de datos llamada IdAsString, pero esto obviamente hace que Entity Framework sea muy infeliz.

Al final, me di cuenta de que no valía la pena todo el tiempo que le dedicaba, y dejé de usar LINQ por completo. Esto funciona bien, pero sería bueno saber si hay una forma "correcta" de hacer esto que realmente funcione.

Ésta es mi solución de trabajo actual:

public IEnumerable<SelectListItem> Categories 
    { 
     get 
     { 
      var dal = new DataAccess(); 
      var categories = dal.Categories; 
      var items = new List<SelectListItem>(); 

      foreach (var category in categories) 
       items.Add(new SelectListItem 
        { 
         Value = category.Id.ToString(), 
         Text = category.Description 
        }); 

      return items; 
     } 
    } 

Así que si alguien ya está haciendo esto y piensan que están haciendo de la manera "correcta", entonces me gustaría saber lo que piensas!

Respuesta

11

Materialice la consulta antes de invocar ToString hará que la última parte sea una consulta no linq-a-entidades. Puede optimizar esto seleccionando solo la identificación y la descripción, llamando a AsEnumerable y luego obteniendo los elementos de la lista de selección.

return new DataAccess() 
     .Categories 
     .OrderBy(c => c.Description) 
     .AsEnumerable() 
     .Select(c => new SelectListItem 
      { 
       Value = c.Id.ToString(), 
       Text = c.Description 
      }); 
+0

Wow. Realmente fue así de simple, ¡gracias! ¡Tenía la sensación de que "debería" ser simple! –

+3

También puede usar 'AsEnumerable' en lugar de' ToList'. Asignar una lista que solo se enumerará no tiene sentido. Con 'AsEnumerable' enumerará cada elemento solo una vez, en vez de dos veces con' ToList'. Si está devolviendo pocos resultados, sin embargo, no habrá ninguna diferencia perceptible. –

Cuestiones relacionadas