2017-06-21 3 views
0

Ich benutze EF v5/6. Ich möchte wissen, wie ich where-Klausel dynamisch erstellen könnte, wenn Benutzer versuchen wird, Suchfilter dynamisch über UI hinzuzufügen. sieheEntity Framework 6: Suchsatz dynamisch gegen DB

die UI ersten enter image description here

jetzt Benutzer am Ende so viele wie Filter durch die oben UI hinzufügen und versuchen, Datenbank zu suchen.

Ich versuche, Google nach einer Lösung als Ergebnis zu suchen, ich kann mehrere Suche zu meiner DB-Tabelle mit EF hinzufügen und ich fand wenige. hier sind einige Links

https://stackoverflow.com/a/5595591/6188148

https://stackoverflow.com/a/24824290/6188148

die obige Führungslinie ist schwer für mich zu verstehen. also schaue ich etwas leicht.

Link Bit Nähe meiner Forderunghttps://stackoverflow.com/a/16646241/6188148 aber immer noch ich bekommen Idee bin nicht wie ihr Code anpassen für mein Szenario zu verwenden.

so meine Anfrage kann jemand mit einem kleinen Beispielcode helfen, die mir helfen, die Dinge zu erledigen.

+0

mit Leistung im Verstand für eine erweiterte Suche wie diese, würde ich empfehlen, ein spezielles Produkt verwenden, wie [Elasticsearch] (https://www.elastic.co/), ich Tage damit verbracht, etwas ähnliches im Innern zu tun von EF entdecken nur, wie schlecht es bei größeren Daten funktioniert. – uk2k05

+0

Elasticsearch kann Daten von SQL-Server mit EF abrufen ..... ich habe keine Ahnung. –

Antwort

3

Ich nehme an, Sie können eine Unterbedingung aus jeder Zeile in Ihrer GUI erstellen. Zum Beispiel würde die erste Zeile

string userInputName = "john"; 
Expression<Func<Person, bool>> condition1 = person => person.Name.Contains(userInputName); 

ähnlich sein und kann als

var selection = db.Persons.Where(condition1).ToList(); 

für mehr Unter Bedingungen verwendet werden, and ist nur eine Verkettung von Where Bedingungen:

var conditions = new List<Expression<Func<Person, bool>>>() { condition1, condition2, ... }; 

IQueryable<Person> query = db.Persons; 
foreach (var condition in conditions) 
{ 
    query = query.Where(condition); 
} 
var selection = query.ToList(); 

Der etwas schwierigere Teil kommt mit den or Bedingungen. Angenommen, Sie haben Ihre Bedingungen in Gruppen von alternativen and Bedingungen (disjunctive normal form) normalisiert, dann erhalten Sie mehrere Gruppen gültiger Ergebnisse. Aus Gründen der Einfachheit, halte ich es in zwei Gruppen hier, aber es kann auf die gleiche Weise wie die and Bedingungen verallgemeinert werden:

Die or kann durch den Union Betrieb auf Unterabfragen dargestellt werden.

Ein paar letzte Worte: Betrachten Sie stattdessen einige etablierte Filter/Such-Frameworks. Dieser Ansatz ist wahrscheinlich weder der schönste noch der schnellste, den Sie finden können.


Wie gewünscht, ein kleines Beispiel mit einigen In-Memory-Daten. Beachten Sie, dass dies nicht 100% äquivalent zu Linq-to-Entities ist. Zum Beispiel wird der String-Vergleich unterschiedlich mit Groß- und Kleinbuchstaben behandelt, und möglicherweise ist nicht jede Bedingung für SQL erlaubt.

public enum TypeOfContact 
{ 
    Unknown, 
    Email 
} 
public class Person 
{ 
    public string Name { get; set; } 

    public DateTime Birth { get; set; } 

    public TypeOfContact ContactType { get; set; } 

    public string ContactValue { get; set; } 
} 

public class Program 
{ 
    static void Main(string[] args) 
    { 
     // test data to simulate a database table 
     var Persons = new List<Person> 
     { 
      // + All conditions met 
      new Person { Name = "john doe", Birth = new DateTime(2011, 1, 1), ContactType = TypeOfContact.Email, ContactValue = "[email protected]" }, 
      // - Not in result 
      new Person { Name = "danny doe", Birth = new DateTime(2012, 1, 1), ContactType = TypeOfContact.Email, ContactValue = "[email protected]" }, 
      // + Name contains john 
      new Person { Name = "john doe", Birth = new DateTime(2013, 1, 1), ContactType = TypeOfContact.Unknown, ContactValue = "" }, 
      // + Birth, ContactType and ContactValue correct 
      new Person { Name = "justin", Birth = new DateTime(2014, 1, 1), ContactType = TypeOfContact.Email, ContactValue = "[email protected]" }, 
      // - Not in result because Name and Birth are wrong 
      new Person { Name = "jonny", Birth = new DateTime(1979, 1, 1), ContactType = TypeOfContact.Email, ContactValue = "[email protected]" }, 
      // - Not in result 
      new Person { Name = "jenny doe", Birth = new DateTime(2016, 1, 1), ContactType = TypeOfContact.Unknown, ContactValue = "" }, 
     }.AsQueryable(); 

     // single-line-conditions 
     Expression<Func<Person, bool>> c1 = p => p.Name.Contains("john"); 
     Expression<Func<Person, bool>> c2 = p => p.Birth.Date >= new DateTime(1980, 1, 1); 
     Expression<Func<Person, bool>> c3 = p => p.ContactType == TypeOfContact.Email; 
     Expression<Func<Person, bool>> c4 = p => p.ContactValue.EndsWith("@email.com"); 

     // DNF groups: outer list = or; inner list = and 
     // c1 or (c2 and c3 and c4) 
     var conditionList = new List<List<Expression<Func<Person, bool>>>> 
     { 
      new List<Expression<Func<Person, bool>>> 
      { 
       c1, 
      }, 
      new List<Expression<Func<Person, bool>>> 
      { 
       c2, 
       c3, 
       c4, 
      }, 
     }; 

     var andSubResults = new List<IQueryable<Person>>(); 
     foreach (var andQueries in conditionList) 
     { 
      var subQuery = Persons; 
      foreach (var andQuery in andQueries) 
      { 
       subQuery = subQuery.Where(andQuery); 
      } 
      andSubResults.Add(subQuery); 
     } 
     var query = andSubResults.FirstOrDefault(); 
     foreach (var subResult in andSubResults.Skip(1)) 
     { 
      query = query.Union(subResult); 
     } 
     var selection = query.ToList(); 
     // just check the result in debugger 
    } 
} 
+0

Ich möchte nur eine kleine Anfrage können Sie mir kleine, aber voll funktionsfähige Beispiel zu diesem Thema, wenn möglich. danke –

+0

Ich würde gerne für Bedingung Iterationsschleife in Ihrem Beispiel hervorgehoben gehen. sagen Sie dies ....... 'var conditions = new Liste >>() {condition1, condition2, ...}; IQueryable query = db.Persons; foreach (var Bedingung in Bedingungen) { query = query.Where (Bedingung); } var selection = query.ToList(); ' –

+2

@MonojitSarkar ein * kleines aber voll funktionsfähiges Beispiel * würde beinhalten, um eine tatsächliche Datenbank einzurichten, weil es sonst nur ein In-Memory-Beispiel ist, das ein bisschen anders funktioniert als linq- Zu-Entitäten. Ich denke, das würde den Rahmen einer Antwort sprengen. Ich werde immer noch ein kleines In-Memory-Beispiel schreiben. – grek40