Frage

Ich habe eine Datenbanktabelle namens Anruf mit Spalten call_time, Standort, emergency_type und es gibt drei Arten von Notfällen: Sanitäter, Polizei und Feuerwehr. In den Fenstern bilden habe ich Checkboxes ‚Rettungssanitäter‘, ‚Polizei‘, ‚Feuerwehr‘ und ich möchte alle Tabellenspalten abzurufen, die die Auswahl des Benutzers entsprechen.

Ich habe eine Funktion:

public static DataTable GetHistory(DateTime from, DateTime to, bool paramedics, bool police, bool firefighters)
    {
        string select =
            "SELECT call_time, location, emergency_type where call_time between @from AND @to AND";
        if(paramedics)
        {
            select += " emergency_type = 'paramedics' ";
        }
        if(paramedics && police)
        {
           select +=" emergency_type = 'paramedics' OR emergency_type = 'police';
        }
        ...

    }

Dieser Code jedoch scheint sehr schmutzig, weil, wenn es 30 Arten von Notfall gab es 30 sein würde! Kombinationen und ich würde alt werden vor allem, wenn Aussagen zu schreiben.

Ich würde mich freuen, wenn Sie Ihre Praxis gemeinsam genutzte Daten für das Abrufen, die die ausgewählten Suchbedingungen erfüllen, wenn es viele Möglichkeiten sind, können Sie chosse.

Danke!

War es hilfreich?

Lösung

Nun, wenn Sie emergency_type als String zu verwenden, haben dann stattdessen in bools zugeben Sie in einer Liste enthalten, die Textdarstellung des Notfalltyps senden könnte. Zum Beispiel den obigen Code anpassen können Sie die Methodensignatur ändern

public static DataTable GetHistory(DateTime from, DateTime to, List<string> types)
{
 ..
}

und dann in einer Liste übergeben, wie diese (zum Beispiel) sah

List<string> types = 
  new List<string> { "paramedics" };

or 

List<string> types = 
  new List<string> { "paramedics", "police" };

Dann können Sie Ihre Anfrage anpassen die SQL-IN-Anweisung in der Where-Klausel zu verwenden. Als nächstes konvertieren wie die Liste der Strings in eine durch Kommata getrennte Zeichenfolge

string values = "'paramedics', 'police'"

Eine einfache Möglichkeit, die Werte Variable zu erstellen, ist die Verwendung

string values = string.Empty;
            types.ForEach(s =>
            {
               if (!string.IsNullOrEmpty(values))
                   values += ",";
               values += string.Format("'{0}'", s);

            });

Durch die Art und Weise können Sie einen parametrisierte Befehl verwenden, um SQL-Injection zu vermeiden. Sobald Sie die Zeichenfolge haben, können Sie einfach tun

string select =
 "SELECT call_time, location, emergency_type where call_time between @from AND @to AND emergency_type IN " + values

Andere Tipps

Dies ist eine schmutzige Art und Weise, dies zu tun.

string select = "SELECT call_time, location, emergency_type where call_time between @from AND @to AND (1=0";

if(paramedics) { select += " OR emergency_type = 'paramedics' "; }
if(police)     { select += " OR emergency_type = 'police'"; }
if(xyz)        { select += " OR emergency_type = 'xyz'"; }

select += ")";

String Verkettung sollte vermieden werden, da es zu einigen fiesen Lücken beitragen kann. Wenn Sie sich für die besten Praktiken in Bezug auf die programmatischen Zugriff suchen, dann ist die beste Praxis hier ist eine parametrisierte Abfrage zu verwenden.

Wenn Sie billig sein wollen, dann machen die in Klausel einen Parameter übernehmen, und verketten die Zeichenfolge zusammen aus der Liste der überprüften Kontrollkästchen, und übergeben, daß, wenn der Wert des Parameters für die in-Klausel. es würde wie folgt aussehen:

where ... and emergency_type in (?)

Der andere Weg, es zu tun ist, um die Anzahl der Kontrollkästchen zu zählen, die überprüft werden, und die Liste der Parameter auf den in Klausel zu bauen, so dass es wie folgt aussieht:

where ... and emergency_type in(?,?...) -- as many params as there are checked checkboxes.

Jede dieser tut einfach gut. Mit dieser Art von Abfragen, habe ich so weit gegangen meine eigenen SQL Konstruktormethoden zu bauen, halte ich eine interne Zählung von Parametern und deren Datentypen und dynamisch die SQL baut, dann bereitet die mit der bekannten Liste von guten Parametern .

Sie könnten lernen Linq aussehen.

Erstellen der Liste der Benutzer vergleichen Werte (@EmergencyList) und verwenden SQL mit einer parametrisierten Abfrage mit dem Operator enthält.

SELECT call_time, 
       location, 
       emergency_type 
where call_time between @from AND @to 
  AND CONTAINS( Emegency_Type, @EmergencyList )
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top