Hallo
Ich verwende momentan folgende Abfrage um Daten zu filtern von SQL Server via LINQ.
internal static List<Team> FilteredActiveItems(Entity entity)
{
//Teams
List<Team> filteredTeams = TeamHandler.ActiveItems;
for (int i = filteredTeams.Count - 1; i >= 0; i--)
{
bool exists = false;
foreach (EntityTeam obj in filteredTeams[i].EntityTeam)
{
if (obj.Entity.EntityId == entity.EntityId)
{
exists = true;
break;
}
}
if (!exists) filteredTeams.RemoveAt(i);
}
return filteredTeams;
}
Grundsätzlich mal werden zuerst alle Teams der filteredTeams Liste zugewiesen. Nachher wird durch diese Liste iteriert und solche Teams gelöscht die keine Entsprechendes "Entity" zugewiesen haben. Danach die modifizierte Liste zurückgegeben.
Einem Team können mehrere Entitys zugewiesen sein und einem Entity mehere Teams. (n:n über Zwischentabelle)
Performancemässig sehr langsam. Gibt es da bessere Lösungen? Oder wie sieht ein LINQ Query aus für so einen Anwendungsfall?
Danke!
Hallo,
so wie ich das sehe sind ja in TeamHandler.ActiveItems
schon alle Einträge aus der DB enthalten. Das ist ja das eigentliche Problem und nicht die zwei for-schleifen zum filtern. Du solltest bei der DB-Selektion der Einträge schon darauf achten, dass du nur die relevanten Einträge holst.
Ja, das ist schon so, aber ich weis nicht genau wie die LINQ Abfrage formulieren bei n:n Beziehungen, das ist mein Hauptproblem.
In Linq wäre das dieser Ein(Zwei)zeiler:
TeamHandler.ActiveItems.RemoveAll(item => !item.EntityTeam.Any(obj => obj.Entity.EntityId == EntityId));
return TeamHandler.ActiveItems;
oder wenn die Urpsrungsauflistung nicht geändert werden soll:
return TeamHandler.ActiveItems.Where(item => item.EntityTeam.Any(obj => obj.Entity.EntityId == EntityId));
Aber ich sehe das auch so, dass es keinen Sinn macht listen zu verwenden. So holst du dir ja immer alle Items vom Server.
PS: Ist es gewollt, dass TeamHandler.ActiveItems auch geändert wird? Das passiert nämlich
Ja das geht super, danke!
Du hast geschrieben:
PS: Ist es gewollt, dass TeamHandler.ActiveItems auch geändert wird? Das passiert nämlich
Ich weis schon, ich weise die filtered Instanz den ActiveItems zu, aber beim Debuggen wird nie etwas aus ActiveItems gelöscht??!!? Was ist ja auch nicht will... Aber wieso ist das so?
So ist es implementiert:
internal static List<Team> ActiveItems
{
get { return DbAccess.GetNewDataContext().Team.Where(obj => !obj.Inactive).OrderBy(obj => obj.Company).ToList(); }
}
Oh ich bin davon ausgegangen dass das Property eines mit backing field ist. So passiert natürlich nichts.
Du solltest versuchen das Laden der Items erst durchzuführen, wenn du vorher alle Filter angewand hast, also zuerst die Where Bedingungen, und dann das ToList, dann werden die Items auf dem Datenbankserver gefiltert.
LG pdelvo
Hallo binaryblog
Ich weis schon, ich weise die filtered Instanz den ActiveItems zu, aber beim Debuggen wird nie etwas aus ActiveItems gelöscht??!!? Was ist ja auch nicht will... Aber wieso ist das so?
Weil du in der ActiveItems-Eigenschaft ein .ToList() machst, damit wird immer eine neue Liste beim nächsten Zugriff auf die Eigenschaft erstellt.
Diese Liste die vorher zurückgegeben wurde und die du verändert hast, wird dann also verworfen.
Gruss Peter
--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011
Ok, danke allen für die Antworten!
Werde das Filtern mal grundsätzlich überarbeiten...!