visual tutorial studio sintaxis questions query que northwnd net mvc microsoft language integrated funciona framework examen exam ejemplos docs developing curso como asp applications c# linq linq-to-sql

c# - tutorial - LINQ to SQL Peculiarities



sql c# linq (5)

En la primera consulta, ya ha recuperado los datos de la base de datos cuando se ejecuta la segunda línea (var items = ...). Esto significa que la segunda línea se ejecuta en el cliente, donde ToShortDateString puede ejecutarse con bastante felicidad.

En la segunda consulta, porque la selección se ejecuta directamente en una colección IQueryable (dataContext.MyLists), intenta traducir la selección en SQL para procesarla en el servidor, donde no se entiende ToShortDateString, de ahí la excepción "No se pudo traducir ..." .

Para entender esto un poco mejor, realmente necesita comprender la diferencia entre IQueryable e IEnumerable, y en qué punto una consulta Linq To Sql deja de ser IQueryable y se convierte en IEnumerable. Hay muchas cosas en la web sobre esto.

Espero que esto ayude,

Pablo

Estoy encontrando algunas peculiaridades con LINQ to SQL.

Con una consulta relativamente simple, quiero seleccionar algunos campos, pero tengo los campos de fecha formateados como cadenas, que primero obtuve así:

var list = dataContext.MyLists.Single(x => x.ID == myId); var items = from i in list.MyItems select new { i.ID, i.Sector, i.Description, CompleteDate = i.CompleteDate.HasValue ? i.CompleteDate.Value.ToShortDateString() : "", DueDate = i.DueDate.HasValue ? i.DueDate.Value.ToShortDateString() : "" };

Más tarde probé la siguiente consulta, que es exactamente la misma, excepto que estoy consultando directamente desde mi dataContext, en lugar de un elemento en mi primera consulta:

var items = from i in dataContext.MyLists select new { i.ID, i.Sector, i.Description, CompleteDate = i.CompleteDate.HasValue ? i.CompleteDate.Value.ToShortDateString() : "", DueDate = i.DueDate.HasValue ? i.DueDate.Value.ToShortDateString() : "" };

El primero funciona bien, sin embargo, la segunda consulta arroja un:

No se pudo traducir la expresión ''...'' en SQL y no se pudo tratar como una expresión local.

Si elimino las líneas que dan formato a la fecha, funciona bien. Si elimino la verificación .HasValue, también funciona bien, hasta que haya valores nulos.

¿Algunas ideas?

Antonio


Haría la parte SQL sin hacer el formateo, luego haré el formateo en el lado del cliente:

var items = list.MyItems.Select(item => new { item.ID, item.Sector, item.Description, item.CompleteDate, item.DueDate }) .AsEnumerable() // Don''t do the next bit in the DB .Select(item => new { item.ID, item.Sector, item.Description, CompleteDate = FormatDate(CompleteDate), DueDate = FormatDate(DueDate) }); static string FormatDate(DateTime? date) { return date.HasValue ? date.Value.ToShortDateString() : "" }


Tal como lo indica el mensaje de error, la diferencia se debe a lo que se puede hacer a nivel local en forma remota mientras se conecta a SQL.

El código Linq debe ser convertido por Linq a SQL en un comando SQL para los datos remotos: todo lo que se debe hacer localmente no se puede incluir.

Una vez que lo arrastraste a un objeto local (en el primer ejemplo), ya no usa Linq para SQL, simplemente Linq. En ese punto, usted es libre de realizar manipulaciones locales en él.


Tal vez hubo un error de copiar y pegar, o simplemente un error tipográfico en su muestra. Pero si no, este podría ser el problema ...

En la segunda consulta está consultando una colección de listas, mientras que en la primera pregunta estaba consultando los elementos dentro de una lista. Pero no ha ajustado la consulta para dar cuenta de esta diferencia.

Lo que necesitas podría ser esto. Tenga en cuenta las líneas comentadas que no aparecieron en su segunda muestra.

var items = from aList in dataContext.MyLists from i in aList.MyItems // Access the items in a list where aList.ID == myId // Use only the single desired list select new { i.ID, i.Sector, i.Description, CompleteDate = i.CompleteDate.HasValue ? i.CompleteDate.Value.ToShortDateString() : "", DueDate = i.DueDate.HasValue ? i.DueDate.Value.ToShortDateString() : "" };