Wie kann ich die Entity-Framework-Abfragen dynamisch?
Ich bin ganz neu bei Entity Framework und ich habe eine Frage zum filtern von Daten.
Habe ich zwei verschiedene Log-Einheiten, Sie sind: DiskLog
und NetworkLog
. Diese Entitäten sind abgeleitet aus Log
Einheit. Hier ist ein code aus meiner C# app:
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 ...
}
Natürlich, ich habe bereits eine funktionierende app und Datenbank-Tabellen erstellt. Was ich will zu tun ist, um die Funktion GetWithFilter Arbeit. Ich habe mehrere der Ausführung Möglichkeiten, die es gibt:
-
if logType == LogType.Disk && computerId <= 0
(es bedeutet, dass es keine Notwendigkeit zu verwenden computerId parameter in der Abfrage, wählen Sie DiskLog Entitäten nur) -
if logType == LogType.Disk && computerId > 0
(bedeutet, ich habe mit computerId parameter, wählen Sie DiskLog Entitäten nur) -
if logType == LogType.NotInitialized && computerId <= 0
(keine Notwendigkeit zu verwenden computerId und logType, wählen Sie einfach die Entitäten, DiskLog und NetworkLog) -
if logType == LogType.NotInitialized && computerId > 0
(wählen Sie alle Arten von Protokolle für bestimmte computer) -
if logType == LogType.Network && computerId <= 0
(wählen Sie alle NetworkLog Personen) -
if logType == LogType.Network && computerId > 0
(wählen Sie alle NetworkLog Entitäten für den angegebenen computer)
Wie Sie sehen können, es gibt viele Optionen verfügbar. Und ich habe zu schreiben 6 Anfragen wie diese:
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();
Also die Frage ist, wie kann ich den code optimieren? Wo ist der Weg, es besser zu machen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie ganz einfach mit dem Abfrage-compossition.
Du das erste mal mit der Abfrage.
Sie, die Sie verfassen, sub-queries.
Und ich würde empfehlen, mit nullable-Wertetypen für die Fälle, wenn es keinen Wert.
Können Sie
Func<T,bool>
um dies zu optimieren,Dann verwenden:
Neue Fabrik für diese Funktionen