update query multiple inner framework data consulta columns c# linq entity-framework linq-to-sql

c# - query - Linq-Agrupando por fecha y seleccionando conteo



query data entity framework (4)

Actualmente estoy trabajando en un problema en el que me gustaría ejecutar una consulta que agrupa los resultados por la fecha seleccionada.

Para este ejemplo, imagine un modelo simple como este:

public class User { public DateTime LastLogIn {get; set;} public string Name {get; set;} }

La solución que estoy buscando es obtener un recuento de los usuarios registrados por fecha. En la base de datos, DateTime se almacena con los componentes de fecha y hora, pero para esta consulta realmente solo me importa la fecha.

Lo que actualmente tengo es esto:

context.Users .Where((x.LastLogIn >= lastWeek) && (x.LastLogIn <= DateTime.Now)) .GroupBy(x => EntityFunctions.TruncateTime(x.LastLogIn)) .Select(x => new { Value = x.Count(), Day = (DateTime)EntityFunctions.TruncateTime(x.Key) }).ToList();

Lo anterior, sin embargo, devuelve una lista vacía.

El objetivo final es tener una Lista de objetos, que contenga un Valor (el recuento de usuarios registrados en un día) y un Día (el día en cuestión)

¿Alguna idea?

Al cambiar la consulta a:

context.Users .Where((x.LastLogIn >= lastWeek) && (x.LastLogIn <= DateTime.Now)) .GroupBy(x => EntityFunctions.TruncateTime(x.LastLogIn)) .Select(x => new { Value = x.Count(), Day = (DateTime)x.Key }).ToList();

ahora devuelve una lista con un solo elemento, con el valor como el recuento total de usuarios que coinciden con la cláusula where y el día como el primer día. Todavía no parece poder agruparse por días.

NOTA: Resulta que el código anterior es correcto, solo estaba haciendo otra cosa mal.

El Sql que está generando es (tenga en cuenta que podría haber errores sintácticos muy leves aquí, al ajustarlo para el ejemplo):

SELECT 1 AS [C1], [GroupBy1].[A1] AS [C2], CAST( [GroupBy1].[K1] AS datetime2) AS [C3] FROM ( SELECT [Filter1].[K1] AS [K1], COUNT([Filter1].[A1]) AS [A1] FROM ( SELECT convert (datetime2, convert(varchar(255), [Extent1].[LastLogIn], 102) , 102) AS [K1], 1 AS [A1] FROM [dbo].[Users] AS [Extent1] WHERE (([Extent1].[LastLogIn] >= @p__linq__1) AND ([Extent1].[LastLogIn] <= @p__linq__2) ) AS [Filter1] GROUP BY [K1] ) AS [GroupBy1]


No necesitas el segundo TruncateTime allí:

context.Users .Where((x.LastLogIn >= lastWeek) && (x.LastLogIn <= DateTime.Now)) .GroupBy(x => EntityFunctions.TruncateTime(x.LastLogIn)) .Select(x => new { Value = x.Count(), // Replace the commented line //Day = (DateTime)EntityFunctions.TruncateTime(x.Key) // ...with this line Day = (DateTime)x.Key }).ToList();

GroupBy ha truncado la hora desde DateTime , por lo que no necesita volver a llamarla.

Para usar EntityFunctions.TruncateTime , deberá hacer referencia al conjunto System.Data.Entity y luego incluir el using System.Data.Objects;


Prueba esto:

.GroupBy(x => new {Year = x.LastLogIn.Year, Month = x.LastLogIn.Month, Day = x.LastLogIn.Day) .Select(x => new { Value = x.Count(), Year = x.Key.Year, Month = x.Key.Month, Day = x.Key.Day })


Puedes hacerlo fácilmente:

yourDateList.GroupBy(i => i.ToString("yyyyMMdd")) .Select(i => new { Date = DateTime.ParseExact(i.Key, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None), Count = i.Count() });


También puedes hacerlo en una sola línea.

var b = (from a in ctx.Candidates select a) .GroupBy(x => x.CreatedTimestamp.Date).Select(g => new { Date=(g.Key).ToShortDateString(), Count = g.Count() });