Heredé una aplicación y necesito agregar una nueva función, pero la base de datos existente está mal diseñada, al igual que la aplicación.
Necesito extraer con una consulta LINQ todos los empleados y el recuento de sus documentos y cuántos de ellos se han abierto.
Para contar los documentos hago un count() , y para los números abiertos tengo un campo booleano que indica si el documento ha sido abierto o no. Si este último fuera un número entero con valor 0 o 1, habría sido muy fácil, solo una suma de este campo.
También intenté hacerlo con el booleano pero falla, ya que no puedo usar convert.toInt32 en Linq-to-Entities:
var employees = from e in context.Employees join d in context.EmployeeDocuments on e.EmployeeId equals d.EmployeeId into dj from d in dj.DefaultIfEmpty() group new { e, d } by new { e.EmployeeId, e.FirstName, e.LastName, e.FiscalCode, e.IdentificationNumber, e.EmploymentStartDate } into g select new EmployeeListItem { EmployeeId = g.Key.EmployeeId, FirstName = g.Key.FirstName, LastName = g.Key.LastName, FiscalCode = g.Key.FiscalCode, IdentificationNumber = g.Key.IdentificationNumber, EmploymentStartDate = g.Key.EmploymentStartDate.ToString("dd/MM/yyyy"), DocumentCount = g.Count(), DocumentOpened = g.Sum(s => Convert.ToInt32(sdDownloadedByEmployee)) };¿Alguna sugerencia o solución alternativa sin realizar cambios en la base de datos?
Tenga en cuenta que esta consulta devuelve un IQueryable , porque necesito devolver un conjunto de resultados paginados, por lo tanto, no puedo volcar las entidades en una lista y luego manipular los datos.
ACTUALIZAR
La solución de Ivan es perfecta y, como todavía estoy atascado en .Net Core 3.1, necesito usar la suma condicional, que se traduce en la siguiente consulta SQL:
SELECT [e].[EmployeeId], [e].[FirstName], [e].[LastName], [e].[FiscalCode], [e].[IdentificationNumber], [e].[EmploymentStartDate], COUNT(*), COALESCE(SUM(CASE WHEN [e0].[DownloadedByEmployee] = CAST(1 AS bit) THEN 1 ELSE 0 END), 0) FROM [Employees] AS [e] LEFT JOIN [EmployeeDocuments] AS [e0] ON [e].[EmployeeId] = [e0].[EmployeeId] GROUP BY [e].[EmployeeId], [e].[FirstName], [e].[LastName], [e].[FiscalCode], [e].[IdentificationNumber], [e].[EmploymentStartDate]Si este último fuera un número entero con valor 0 o 1, hubiera sido muy fácil, solo una suma de este campo
Bueno, puede convertir fácilmente el valor bool en 0 o 1 valor int usando el operador condicional estándar, por ejemplo
g.Sum(s => sdDownloadedByEmployee ? 1 : 0)En EF Core 5.0+, también puede usar el recuento condicional (en EF6 y antes de EF Core 5.0, está atascado con la suma condicional):
g.Count(s => sdDownloadedByEmployee)