2016-05-04 11 views
0

Ich erstelle eine API mithilfe der Web-API, wobei ich Datenbanktabellen als JSON zurückgebe.Dynamische Web-API-Parameter zum Filtern

Das ist mein Controller-Methode:

public List<ExampleDataDTO> ExampleData(int offset = 0, int limit = 0) 
{ 
    return DataAccessLayer.GetExampleData(offset, limit); 
} 

Data Access-Methode:

public List<ExampleDataDTO> GetExampleData(int offset, int limit) 
     { 
      using (var db = new Context()) 
      { 
       db.Configuration.ProxyCreationEnabled = false; 
       var exampleQuery = db.example.AsEnumerable().Select(item => 
       new ExampleDataDTO 
       { 
        //Selects 
       }); 

       if(offset == 0 && limit == 0) 
       { 
        return exampleQuery .ToList(); 
       } 
       else 
       { 
        return exampleQuery .Skip(offset).Take(limit).ToList(); 
       } 
      } 
     } 

Jetzt enthält die ExampleDataDTO über 100 Dateien, und ich möchte in der Lage sein, Daten mit der API auf ein beliebiges Feld zu filtern .

Gibt es eine Möglichkeit, dynamische Abfrageparameter zu erstellen? Wenn ich beispielsweise zu localhost/api/ExampleData?offset=0&limit=10&name=test1&size=test2 gehe, möchte ich die Schlüssel und Werte für Name und Größe erhalten, um sie in meinen LINQ-Code aufnehmen zu können.

Ist das machbar?

EDIT:

ich alle Parameter als IEnumerable<KeyValuePair<String, String>> queryString

bekommen kann, ist es eine Möglichkeit, den Schlüssel in einem Lambda-Ausdruck zu verwenden i durch alle keyValuePairs Schleife waren? wie Wo (c = c.Key == Value),

foreach(var queryKeyValuePair in queryString) 
{ 
    Something including Where(c => c.queryKeyValuePair.Key == queryKeyValuePair.Value) 
} 
+0

was ist name, test1, größe, test2? Können Sie Ihr DTO-Objekt auch teilen? –

+0

Ich bin mir sicher, dass Sie eine LINQ-Anweisung erstellen können, die alle verschiedenen Permutationen der Anforderungsparameter berücksichtigt, aber Sie möchten auch sicherstellen, dass die SQL, die LINQ generiert, gut funktioniert. Persönlich habe ich es in diesen Fällen besser gefunden, eine SQL-Prozedur zu erstellen, um die möglichen Parameter zu akzeptieren und sicherzustellen, dass sie mit den verschiedenen Kombinationen gut funktioniert. –

+0

Ich sehe, dass Sie ein 'Skip() verwenden. Take()'. Wie ist die Liste geordnet? Ist es möglich, dass sich die Anforderungen ändern, um sie anders anzuordnen, oder im schlimmsten Fall, dass der Benutzer der API sie so anordnet, wie sie es für richtig halten? –

Antwort

1

Wenn ich Ihre Frage richtig verstanden habe, möchten Sie vielleicht so etwas wie dies tun:

public List<ExampleDataDTO> GetExampleData(int offset = 0, int limit = 0, string name = "", string size = "") 
{ 
    using (var db = new Context()) 
    { 
     db.Configuration.ProxyCreationEnabled = false; 
     var exampleQuery = db.example 
      .Where((x => x.Name == name || name == "") && // If parameter 'name' has a value, filter on that, else ignore it. 
        (x => x.Size == size || size == "")) // If parameter 'size' has a value, filter on that, else ignore it. 
      .AsEnumerable() 
      .Select(item => 
      new ExampleDataDTO 
      { 
       //Selects 
      }); 

     if (offset == 0 && limit == 0) 
     { 
      return exampleQuery.ToList(); 
     } 
     else 
     { 
      return exampleQuery.Skip(offset).Take(limit).ToList(); 
     } 
    } 
} 

die Parameter Ihrer Methode Stellen optional und verwende sie in der LINQ-Abfrage zum Filtern.

+0

Meine Frage wurde aktualisiert –

1

Sie können OData mit Ihren WebAPI-Controllern dynamisch anwenden: filter, orderby, select, skip, top (take).

Zum Beispiel:

// your API action 
public IQueryable<ExampleDataDTO> Get(ODataQueryOptions opts) 
{ 
    // here is some odata settings to validate query params. 
    var settings = new ODataValidationSettings() 
    { 
     // Initialize settings as needed. 
     AllowedFunctions = AllowedFunctions.AllMathFunctions 
    }; 

    // validating parameters 
    opts.Validate(settings); 

    var yourExampleQuery = // some data from db 

    // apply all parameters that came within query to your data 
    IQueryable results = opts.ApplyTo(yourExampleQuery.AsQueryable()); 

    // and return this 
    return results as IQueryable<Product>; 
} 

Und Ihre Frage könnte so etwas wie sein: http://localhost/ExampleData?$filter=SomeProperty eq 'SomeValue' $orderby=anotherProperty & $skip=10 & $top=10

Alle Abfrageparameter werden in ODataQueryOptions analysiert werden und auf Ihr API-Aufruf Ergebnis.

Ich hoffe, es wird helfen.

Verwandte Themen