2011-04-30 32 views
8

Tengo una clase de entidad con fecha y hora archivada, quiero seleccionar el formato 'mon-yyyy' distinto del valor de fecha y hora y completar la lista desplegable.Fecha de formateo en la consulta Linq-to-Entities causa la excepción

el siguiente código me da el error: Mensaje de

var env = db.Envelopes.Select(d => new 
     { 
      d.ReportDate.Year, 
      d.ReportDate.Month, 
      FormattedDate = d.ReportDate.ToString("yyyy-MMM") 
     }).Select(d => d.FormattedDate) 

    List<SelectListItem> _months = new List<SelectListItem>();   

    foreach (var mname in env) 
    { 
     _months.Add(new SelectListItem() { Text = mname, Value = mname }); 
    } 

error:

LINQ to Entities does not recognize the method 'System.String ToString(System.String)' method, and this method cannot be translated into a store expression.

¿Cómo puedo corregir este mensaje de error?

Gracias SR

Respuesta

13

Recuerde que la consulta va a ser traducido a SQL y enviado a la base de datos. Su intento de formatear la fecha no es compatible con la consulta, por lo que está viendo ese mensaje de error en particular. Debe recuperar los resultados y luego formatee una vez que los datos se hayan materializado.

Una opción es simplemente seleccionar la fecha tal como está. A medida que itera sobre el resultado, formatéelo como lo agrega a su lista. Pero también puede lograr la construcción de la lista con la fecha formateada en una declaración única utilizando el método de encadenamiento.

List<SelectListItem> _months = db.Envelopes.OrderByDescending(d => d.ReportDate) 
     .Select(d => d.ReportDate) 
     .AsEnumerable() // <-- this is the key method 
     .Select(date => date.ToString("MMM-yyyy")) 
     .Distinct() 
     .Select(formattedDate => new SelectListItem { Text = formattedDate, Value = formattedDate }) 
     .ToList(); 

El método .AsEnumerable() obligará a la ejecución de la primera porción de la consulta en la base de datos y el resto va a trabajar con los resultados en la memoria.

+0

@Anthony Pegram: gracias por la respuesta. desde su código, quiero obtener el valor distinto y el orden por ReportDate en orden descendente. donde necesito agregar estos dos en tu código. – sfgroups

+0

He actualizado la respuesta para incluir una clasificación de fecha descendente y una distinta antes de la llamada 'AsEnumerable()'. Estos serán luego parte del SQL y manejados por la base de datos. –

+0

@Anthony Pegram, lo siento, mi pregunta no está clara, creo. Quiero obtener el valor 'aaaa-MMM' distinto, no la fecha de informe distinta. – sfgroups

8

Aquí hay una alternativa:

.Select(p -> SqlFunctions.StringConvert((double) 
        SqlFunctions.DatePart("m", p.modified)).Trim() + "/" + 
       // SqlFunctions.DateName("mm", p.modified) + "/" + MS ERROR? 
       SqlFunctions.DateName("dd", p.modified) + "/" + 
       SqlFunctions.DateName("yyyy", p.modified) 

Al parecer DateName("MM", ..) se detalla el nombre del mes en que DatePart("mm", ..) proporciona un valor numérico, por lo tanto el StringConvert(), pero esta almohadillas izquierda el resultado con espacios, por lo tanto, la .Trim().

Al igual que Anthony Pegram dijo anteriormente, esto sucede en la base de datos en lugar de en C# (.AsEnumerable() tira de todos los datos locales a C# así que asegúrese de filtrar los datos antes de usarlo.)

Obviamente te gustaría reorganizar la salida se ajusta ligeramente a yyyy-MM y usa DatePart para el dígito o DateName para el nombre del mes.

+4

Me encanta la respuesta, pero me mata cuando las personas usan clases sin indicar el espacio de nombres donde se puede encontrar la clase. SqlFunctions está en el espacio de nombres System.Data.Objects.SqlClient. Necesitará una referencia al ensamblado System.Data.Entity en su proyecto para encontrarlo. – Tim

+0

Muy útil, gracias. – hncl

1

Aquí hay una alternativa que usa el formato común dd/MM/aaaa. confirmó el SQL Server 2012 con Entity Framework 5

invoices.Select(i => new 
{ 
    FormattedDate = ( EntityFunctions.Right(String.Concat(" ", SqlFunctions.StringConvert((double?) SqlFunctions.DatePart("dd", i.DocumentDate))), 2) 
         + "/" 
         + EntityFunctions.Right(String.Concat(" ",SqlFunctions.StringConvert((double?) SqlFunctions.DatePart("mm", i.DocumentDate))), 2) 
         + "/" 
         + EntityFunctions.Right(SqlFunctions.StringConvert((double?) SqlFunctions.DatePart("yyyy", i.DocumentDate)), 4) 
         ).Replace(" ", "0") 
} 

Produce fechas en un formato dd/mm/aaaa con ceros a la izquierda.

0

Usé una solución para construir manualmente los formatos que contienen yyyy y MM. Me gustaría mencionar aquí si se puede ayudar a alguien (al menos temporalmente):

FormattedDate = d.ReportDate.Year.ToString() + "-" + d.ReportDate.Month.ToString() 

esto hace que el formato yyyy-MM

Cuestiones relacionadas