verwendetes Datenbanksystem: SQL Server 2008 R2 SP1
Hallo,
ich habe eine Tabelle mit Prozessdaten, die zyklisch aus der Produktion kommen (derzeit ca. 7 Milliarden Zeilen, ~330GB, bei Produktion täglich ca. +1GB).
Diese Daten laufen zwangsweise in die selbe Tabelle.
Nun zeige ich diese Daten in verschiedenen (gefilterten) Ansichten über eine EntityDataSource in einem GridView (ASP.NET, AutoPaging usw.) an.
Jedem Eintrag ist eine Gruppe zugeordnet. Gruppen sind bei uns die verschiedenen Produktionsbereiche (~40). Jetzt wurde die Anforderung gestellt, dass Hans Müller aus der chemischen Vorbehandlung auch nur die Daten aus der chemischen Vorbehandlung einsehen kann. Das wäre nun noch sehr einfach abzubilden mit einem WHERE Group == "chemVorb". Nun gibt es aber Mitarbeiter die 4, 5 oder sogar 20 der 40 Bereiche einsehen dürfen.
Also habe ich eine Entität für Benutzer in meiner DB erstellt, und eine (Viele)-(Viele)-Zuordnung zu den Gruppen vorgenommen.
Jetzt hatte ich mir vorgestellt in die WHERE Klausel so etwas einzubauen: WHERE UserHasAccessRight(....Username, Prozessdatensatz.Group_ID). Wobei UserHasAccessRight eine in .NET definierte Funktion mit Rückgabe eines bool wäre, welche die Gruppenzugehörigkeit prüft. Das funktioniert natürlich nicht, da sich die Funktion nicht in SQL übersetzen lässt.
Muss ich das ganze nun als Stored Procedure realisieren? Gibt es einen anderen Lösungsweg? Ich könnte mir vorstellen, dass die Performance sehr leiden würde, wenn beim Abrufen von vielen Datensätzen für jeden Datensatz die Zugriffsrechte geprüft werden. Andererseits zeige ich die Datensätze ja nur "gepaget" an.
Über Anregungen wäre ich sehr dankbar.
Viele Grüße!
Hallo,
mach doch einen (zusätzlichen) Filter für das DataGrid => "Gruppe" (z.b. als Select-Feld) und hier lässt du nur die Gruppen zur Auswahl anzeigen zu der der User Zugriff hat.
Damit kannst du die Daten dann so wie von dir schon angesprochen mit
where Gruppe == "blafasel" abfragen...
lg
Okay, wäre eine Möglichkeit, aber dann kann ich nicht mehrere Gruppen gleichzeitig anzeigen.
Mir ist gerade eine Idee gekommen. Ich kann die Gruppen_IDs auf die der Nutzer zugreifen darf ja in einem Array zur Verfügung stellen. Kann ich dann in einem LINQ Query sowas wie "WHERE Group_ID ''part of'' array" einfügen? Das wäre sicherlich performanter als dies für jeden Eintrag zu prüfen.
Hallo seeba,
ein WHERE Group_ID IN (...)
wäre eine SQL-Lösung die in Linq mittels
IQueryable<T> query = ...
query.Where(q => groups.Contains(q.Group_ID))
erreicht wird.
Sonst könntest du auch das Where dynamsich mit dem PredicateBuilder zusammenbauen.
mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.
"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
Danke für eure Anregungen.
Ich habe es nun so gelöst:
protected void Page_Load(object sender, EventArgs e)
{
ModelContainer mc = new ModelContainer(ConfigurationManager.ConnectionStrings["ModelContainer"].ToString());
int[] ids = AccessRightChecker.GetGroupsWithDisplayAccessRight(mc, HttpContext.Current.User.Identity.Name);
string idsCsv = String.Join(", ", ids);
EntityDataSource.Where = "it.[Group].ID IN {" + idsCsv + "}";
}
Gibt es eine charmantere Lösung?
Hallo seeba
Mit EF würde ich, wie Gü bereits geschrieben hat, mal versuchen ob's mit Contains
funktioniert.
Mit native ADO.NET würde ich entweder die CSV-Liste der IDs an eine SP übergeben, serverseitig über eine Split-Methode trennen und in eine Temp-Table schreiben mit der man dann joinen kann; oder direkt mit Table Valued Parameters arbeiten.
Grüße
Flo
Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+
Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.
Die Lösung via IN-Operator funktioniert, aber bei großen Datenmengen ist die nicht anzuraten. Hast Du die M:N Beziehungen auch in der DB persistiert? Wenn ja, dann sollte sich das über JOINs lösen lassen und dadurch deutlich effizienter ausgeführt werden können.
Bart Simpson
Praxis ist wenn alles funktioniert und keiner weiss warum.
Theorie ist wenn man alles weiss, aber nichts funktioniert.
Bei uns wird Theorie und Praxis vereint: Nichts funktioniert und keiner weiss warum...