Benutzer mit den meisten Antworten
Performance problems with SQLite and Linq Selection

Frage
-
I can not manage to select the data in a flat structure and detailed
information in a array of the same structure together in one select.
If I do it one after the other, the performance is pretty bad.
Perhaps someone can help me, here is an extract from the structures,
tables and the select statement.
============================================================
--- Database
============================================================
public class MovieDb
{
public string MovieGuid {get; set;}
public string Title {get; set;}
public string Plot {get; set;}
public int Time {get; set;}
public string Langu {get; set;}
public int FSK {get; set;}
...
}
public class ActorDb
{
public string ActorGuid {get; set;}
public string DisplayName {get; set;
public string Firstname {get; set;
public string Lastname {get; set;
...
}
public class ActorsInMovieDb
{
public string MovieGuid {get; set;}
public string ActorGuid {get; set;}
public string Role {get; set;}
}
public class ActorsInMovieDatabaseView
{
public string MovieGuid {get; set;}
public string ActorGuid {get; set;}
public string DisplayName {get; set;}
public string Role {get; set;}
}
============================================================
--- View Classes
============================================================
public class ActorItem
{
public string MovieGuid {get; set;}
public string ActorGuid {get; set;}
public string DisplayName {get; set;}
public string Role {get; set;}
}
public class MovieItem
{
public string MovieGuid {get; set;}
public string Title {get; set;}
public string Plot {get; set;}
public int Time {get; set;}
public string Langu {get; set;}
public int FSK {get; set;}
...
public List<ActorItem> Actors {get; set;}
}
============================================================
--- Select
============================================================
foreach (MovieDb record in database.MovieDb)
{
movieItem = new MediaItem();
mediaItem = MappingMediaItem(record);
// --- Now, select the actors
movieItem.Actors = database.ActorsInMovieDatabaseView.AsNoTracking().Where(x => x.MovieGuid == record.MovieGuid).ToList();
// Select(a => new
// {
// DisplayName = a.DisplayName,
// Role = a.Role
// }
//).ToList();
}
Antworten
-
Hi,
ich würde alle untergeordneten Elemente aller Hauptelemente auf einmal aus der Datenbank abfragen und die Zuweisung dann später in der Schleife vornehmen.
List<Guid> movies = ( from n in database.MovieDb where ... select n ).Distinct().ToList(); List<Guid> movieIds = ( from n in movies select n.MovieGuid ).Distinct().ToList(); List<Actor> actors = ( from n in database.Actors select n ).AsNoTracking().Where( f => movieIds.Contains( f.MovieGuid ) ).ToList(); foreach( MovieDb item in movies) { item.Actors = actors.Where( f => f.MovieGuid == item.MovieGuid ); }
Damit sparst Du dir alle Datenbankzugriffe bis auf zwei (einmal Movies, einmal Actors).
Alternativ (wenn die Objekte auf Datenbankebene oder Codeebene passend aussehen und die Referenzen richtig gesetzt sind) kannst Du die untergeordneten Elemente auch gleich beim ersten Select mit auslesen.
IQueryable<MovieDb> query = ( from n in database.MovieDb .Include( c => c.Actors ) select n );
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport
- Bearbeitet Stefan FalzModerator Donnerstag, 14. Januar 2021 18:48
- Als Antwort markiert MSA Development Samstag, 16. Januar 2021 15:31
Alle Antworten
-
Hi,
ich würde alle untergeordneten Elemente aller Hauptelemente auf einmal aus der Datenbank abfragen und die Zuweisung dann später in der Schleife vornehmen.
List<Guid> movies = ( from n in database.MovieDb where ... select n ).Distinct().ToList(); List<Guid> movieIds = ( from n in movies select n.MovieGuid ).Distinct().ToList(); List<Actor> actors = ( from n in database.Actors select n ).AsNoTracking().Where( f => movieIds.Contains( f.MovieGuid ) ).ToList(); foreach( MovieDb item in movies) { item.Actors = actors.Where( f => f.MovieGuid == item.MovieGuid ); }
Damit sparst Du dir alle Datenbankzugriffe bis auf zwei (einmal Movies, einmal Actors).
Alternativ (wenn die Objekte auf Datenbankebene oder Codeebene passend aussehen und die Referenzen richtig gesetzt sind) kannst Du die untergeordneten Elemente auch gleich beim ersten Select mit auslesen.
IQueryable<MovieDb> query = ( from n in database.MovieDb .Include( c => c.Actors ) select n );
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport
- Bearbeitet Stefan FalzModerator Donnerstag, 14. Januar 2021 18:48
- Als Antwort markiert MSA Development Samstag, 16. Januar 2021 15:31
-
Hi,
ergänzend zu Stefans Beitrag solltest du auch prüfen, ob jedes LinQ-Ergebnis zu persistieren ist (ToList). Möglicherweise ist das nicht erforderlich, spart Zeit und Speicherplatz.--
Best Regards / Viele Grüße
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks