Soy bastante nuevo en Entity Framework y tengo una pregunta sobre el filtrado de datos.¿Cómo puedo crear consultas de Entity Framework dinámicamente?
Tengo dos entidades de registro diferentes, que son: DiskLog
y NetworkLog
. Estas entidades se derivan de la entidad Log
. Aquí hay un código de mi aplicación de C#:
public class Log { ... }
public class DiskLog : Log { ... }
public class NetworkLog : Log { ... }
public enum LogType
{
NotInitialized = 0,
Disk,
Network
}
public List<Log> GetWithFilter(
Guid userKey,
int nSkip,
int nTake,
DateTime dateFrom = DateTime.MinValue,
DateTime dateTo = DateTime.MaxValue,
LogType logType = LogType.NotInitialized,
int computerId = 0)
{
// need to know how to optimize ...
return ...
}
Por supuesto, ya he tablas de aplicaciones y bases de datos de trabajo creados. Lo que quiero hacer es hacer funcionar la función GetWithFilter. Tengo formas varias de ejecución allí:
if logType == LogType.Disk && computerId <= 0
(que significa que no hay necesidad de utilizar el parámetro ComputerID en la consulta, seleccionar sólo las entidades DiskLog)if logType == LogType.Disk && computerId > 0
(significa que tengo que utilizar el parámetro ComputerID, seleccionar sólo las entidades DiskLog)if logType == LogType.NotInitialized && computerId <= 0
(sin necesidad de utilizar ComputerID y logType, sólo tiene que seleccionar todas las entidades, DiskLog y NetworkLog)if logType == LogType.NotInitialized && computerId > 0
(seleccionar todos los tipos de registros de equipo especificado)if logType == LogType.Network && computerId <= 0
(seleccionar todas las entidades NetworkLog)if logType == LogType.Network && computerId > 0
(seleccionar todas las entidades NetworkLog de equipo especificado)
Como se puede ver , hay muchas opciones disponibles. Y llegué a escribir 6 consultas como esta:
1.
context.LogSet
.OfType<DiskLog>
.Where(x => x.Computer.User.UserKey == userKey)
.Where(x => x.DateStamp >= dateFrom && x.DateStamp < dateTo)
.OrderByDescending(x => x.Id)
.Skip(nSkip)
.Take(nTake)
.ToList();
2.
context.LogSet
.OfType<DiskLog>
.Where(x => x.Computer.User.UserKey == userKey)
.Where(x => x.DateStamp >= dateFrom && x.DateStamp < dateTo)
.Where(x => x.Computer.Id == computerId)
.OrderByDescending(x => x.Id)
.Skip(nSkip)
.Take(nTake)
.ToList();
3.
context.LogSet
.Where(x => x.Computer.User.UserKey == userKey)
.Where(x => x.DateStamp >= dateFrom && x.DateStamp < dateTo)
.OrderByDescending(x => x.Id)
.Skip(nSkip)
.Take(nTake)
.ToList(); // simplest one!
4.
context.LogSet
.Where(x => x.Computer.User.UserKey == userKey)
.Where(x => x.DateStamp >= dateFrom && x.DateStamp < dateTo)
.Where(x => x.Computer.Id == computerId)
.OrderByDescending(x => x.Id)
.Skip(nSkip)
.Take(nTake)
.ToList();
5.
context.LogSet
.OfType<NetworkLog>
.Where(x => x.Computer.User.UserKey == userKey)
.Where(x => x.DateStamp >= dateFrom && x.DateStamp < dateTo)
.OrderByDescending(x => x.Id)
.Skip(nSkip)
.Take(nTake)
.ToList();
6.
context.LogSet
.OfType<NetworkLog>
.Where(x => x.Computer.User.UserKey == userKey)
.Where(x => x.DateStamp >= dateFrom && x.DateStamp < dateTo)
.Where(x => x.Computer.Id == computerId)
.OrderByDescending(x => x.Id)
.Skip(nSkip)
.Take(nTake)
.ToList();
Así que la pregunta es ¿cómo puedo optimizar el código? ¿Dónde está la manera de hacerlo mejor?
eso se debe Expresión. Esto filtra los datos en memoria. –
Euphoric