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() : ""
};
ToShortDateString()
no es compatible con Linux en http://msdn.microsoft.com/en-us/library/bb882657.aspx