0

Ich habe diesen Code runtergeworfen, weil es funktioniert hat, aber ich muss wirklich etwas akzeptables umgestalten. Es akzeptiert eine Reihe von Abfrageobjekten (Zeichenfolgen, die wie ProductID = 3 aussehen) und fügt sie dann zu meiner Abfrage hinzu. Dies funktioniert nur für logisches AND, aber ich brauche eventuell ein paar verschiedene logische Operatoren (ODER, NICHT).Entity Framework 4 und Linq to Entities Spezifikationen: Wie wird es codiert?

-- Idea here is add the where clause to the original query and return a new one 
private static IQueryable<Product> GetFilteredQuery(string condition, 
    IQueryable<Product> originalQuery) 
    { 
     -- REPETITION 
     if(-- Regex comparison looking for "productid = 123" --) 
     { 
      returnQuery = originalQuery.Where(
        p => p.myEntity.SelectMany(q => q.subEntity) // spec expression 
          .Any(r => r.id == foundid));   
     } 
     ... (one if statement for each specification, calling this several times) 

ich dies auch für die Bestellung haben:

private static IQueryable<Product> GetOrderedQuery(IList<string> fields, 
    IQueryable<Product> originalQuery) 
{ 
    var resultQuery = originalQuery; 
    bool firstTime = true; 
    foreach(var field in fields) 
    { 
     -- REPETITION 
     if(field == "id") 
     { if(firstTime == true) 
      { resultQuery = resultQuery.OrderBy(p => p.id); 
       firstTime = false; 
      } 
      else 
      { resultQuery = resultQuery.ThenBy(p => p.id); 
      } 
     } 
     ... (one for each field to order by) 
    } 

Wie konnte ich jede Wiederholung in einer Spezifikation Objekt kapseln, wo ich irgendwie diese Sammlung von Spezifikationen zu meiner ursprünglichen Abfrage anhängen können, einschließlich der Bestellung Ausdrücke? Dies ist unter den Linq to Entities, Entity Framework 4 und C# Regenschirm.

Es wäre wirklich nett, so etwas zu tun, was im Wesentlichen das oben genannte ist.

var originalQuery = ...; 
foreach(var spec in mySpecs) 
{ originalQuery = spec(originalQuery); //adds all the where clauses 
} 

originalQuery = orderSpec(originalQuery); // adds all the order fields 

Links zu Websites, Beispielcode, würde sicherlich geschätzt werden.

+0

Bin ich der einzige hier man den Punkt hinter diesen Methoden fehlt? Wäre es nicht einfach, dem Anrufer zu erlauben, die LINQ-Anrufe selbst zu verketten, anstatt zu versuchen, etwas überzuentwickeln, um es vor ihnen zu verbergen? –

+0

Die Felder kommen vom Client. Der Client ist ein Webbrowser, der JSON hin und her sendet. Ich werde durch jeden vom Kunden zur Verfügung gestellten Zyklus radeln und es implementieren müssen. –

+0

Was ist mit der Deserialisierung von JSON zu .NET-Objekt (lassen Sie es Suchbedingungen aufrufen) und erstellen Sie dann Linq to Entities Abfrage für wohlbekannte Suchbedingungen Struktur? –

Antwort

1

Das einzige, was ich sah etwas Ähnliches war:

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

Aber das ist nicht spezifisch für EF 4. Warum nicht die Abfrage Entität SQL-Format konvertieren?

Sie können die Abfrage als String, erstellen und diese Begriffe auf diese SQL-Abfrage anhängen.

HTH.

+0

Nur Problem mit Dynamic SQL ist es nicht stark typisiert. Das Spezifikationsmuster würde stark typisiert sein, wobei Lambda-Ausdrücke verwendet werden, um die Teilnahme anzuzeigen. p => p.name –

+0

Mit Dynamic SQL, stimme ich zu, können Sie Cast verwenden, um in den entsprechenden Typ zu konvertieren. Entity SQL würde funktionieren. –

1

Werfen Sie einen Blick auf LinqSpecs, es könnte tun, was Sie brauchen, oder zumindest geben Sie Ihnen einige Ideen, um damit zu arbeiten.

Von dem, was ich verstehe, könnten Sie in der Lage sein, so etwas wie zu tun:

var originalSpec = ...; 
var composedSpec = originalSpec; 

foreach(var spec in mySpecs) 
{  
    composedSpec &&= spec; //adds all the where clauses 
} 

composedSpec &&= orderSpec; // adds all the order fields