2012-01-17 4 views
5

Sto cercando di generare una query che trova tutti i grandi, cose rosse con un costo maggiore di 3.Come si applica in modo dinamico un operatore condizionale a un campo utilizzando il driver MongoDB-CSharp ufficiale?

Questa domanda sembra essere quello che sto cercando:

{ "color" : "red", "size" : "large", "cost" : { "$gt" : 3.0 } } 

Ma, io sono impossibile trovare un modo elegante per creare la condizione di costo utilizzando il driver CSharp MongoDB ufficiale. Questa è una mod che sembra creare la query:

QueryConditionList gt = Query.GT("cost", BsonDouble.Create(3)); 

QueryDocument query = new QueryDocument(); 
query.Add("color", "red"); 
query.Add("size", "large"); 
query.Add(gt.ToBsonDocument().Elements); 

List<BsonDocument> results = events.Find(query).ToList(); 

Un altro modo per farlo che sembra funzionare è come questo:

QueryDocument query = new QueryDocument(); 
query.Add("color", "red"); 
query.Add("size", "large"); 
query.Add("cost", new BsonDocument("$gt", BsonDouble.Create(3))); 

List<BsonDocument> results = events.Find(query).ToList(); 

Sono uno di questi approcci un buon modo per ottenere questo risultato? C'è un altro?

Ho bisogno di utilizzare tecniche che mi consentono di creare dinamicamente la query e aggiungere campi che saranno coinvolti nella query. Speravo di trovare un modo per aggiungere una condizione tramite query.Add() ma non so se è possibile.

Qualsiasi aiuto è apprezzato.

risposta

6

È possibile utilizzare il generatore di query in tutto, in questo modo:

var query = Query.And(
       Query.EQ("color", "red"), 
       Query.EQ("size", "large"), 
       Query.GT("cost", 3) 
      ); 

aggiornamento Siamo spiacenti, vedo quello che stai chiedendo, ora.

Si potrebbe fare qualcosa di simile, anche:

int i = 0; 
var qc = QueryComplete[3]; 
qc[i++] = Query.EQ("color", "red"); 
qc[i++] = Query.EQ("size", "large"); 
qc[i++] = Query.GT("cost", 3); 
var query = Query.And(qc); 

In questo modo, è comunque possibile utilizzare i metodi di costruttore e l'abbiano in essere dinamico.

+0

Grazie. Il fatto che Query.E restituito un QueryComplete mi stava buttando fuori. Ho continuato a pensare in termini di come puoi costruire un'espressione LINQ. Grazie per aver indicato che richiede un array e non solo operandi. Fondamentalmente ho fatto ciò che hai aggiunto con la tua modifica e sembra funzionare alla grande. – Vyrotek

2

Puoi dati guidare in maniera forza bruta, basta costruire un albero di "QueryElement" e chiamare BuildQuery di costruire in modo ricorsivo come in questo esempio classe:

public class QueryElement 
    { 
     public enum eOperator 
     { 
      AND, OR, EQ, NE, GT, GTE, LT, LTE  //etc. 
     }; 

     public eOperator Operator { get; set; } 

     public string Field { get; set; } 

     public BsonValue Value { get; set; } 

     public List<QueryElement> Children { get; set; } 

     public IMongoQuery BuildQuery() 
     { 
      int i = 0; 
      var qc = new IMongoQuery[(Children!=null)?Children.Count:0]; 

      if (Children != null) 
      { 
       foreach (var child in Children) 
       { 
        qc[i++] = child.BuildQuery(); 
       } 
      } 

      switch (Operator) 
      { 
       // multiple element operators 

       case eOperator.AND: 
        return Query.And(qc); 
       case eOperator.OR: 
        return Query.And(qc); 

       // single element operators 
       case eOperator.EQ: 
        return Query.EQ(Field, Value); 
       case eOperator.NE: 
        return Query.NE(Field, Value); 
       case eOperator.GT: 
        return Query.GT(Field, Value); 
       case eOperator.GTE: 
        return Query.GTE(Field, Value); 
       case eOperator.LT: 
        return Query.LT(Field, Value); 
       case eOperator.LTE: 
        return Query.LTE(Field, Value); 
      } 
      return null; 
     } 
    } 
Problemi correlati