2013-03-03 9 views
8

Sto cercando di interrogare le mie collezioni, ma non sono sicuro di come fare un "aggiungere" di sorta per Query.And()Come utilizzare query e QueryBuilder di MongoDB in C# ciclo foreach?

Ecco il mio modello di dominio per creare il documento Item:

public class Item 
{ 
    public ObjectId Id { get; set; } 
    public string ItemTypeTemplate { get; set; } 
    public string UsernameOwner { get; set; } 

    public IList<ItemAttribute> Attributes { get; set; } 
} 

Il IList<ItemAttribute> cambiamenti di raccolta a seconda ItemTypeTemplate (una sorta di una chiave di ricerca per un elenco predeterminato di attributi di un elemento)

Ecco un esempio di un documento Item:

{ 
    "_id" : ObjectId("5130f9a677e23b11503fee72"), 
    "ItemTypeTemplate" : "Tablet Screens", 
     //can be other types like "Batteries", etc. 
     //which would change the attributes list and values 
    "UsernameOwner" : "user032186511", 
    "Attributes" : [{ 
     "AttributeName" : "Screen Size", 
     "AttributeValue" : "10.1" 
    }, { 
     "AttributeName" : "Pixel Density", 
     "AttributeValue" : "340" 
    }] 
} 

IL PROBLEMA

Data la natura "dinamica" di IList<ItemAttribute>, non posso specificare manualmente le condizioni di query aggiuntive per AttributeName e AttributeValue così ho pensato di utilizzare un ciclo per creare la query:

QueryBuilder<Item> qbAttributes = new QueryBuilder<Item>(); 

foreach (var attribute in item.Attributes) 
{ 
    qbAttributes.And(
     Query.EQ("Attributes.AttributeName", attribute.AttributeName), 
     Query.EQ("Attributes.AttributeValue", attribute.AttributeValue), 
    ); 
} 

var query = Query.And(
    Query.EQ("TemplateId", item.TemplateId), 
    Query.NE("UsernameOwner", item.UsernameOwner) 
); 

return DBContext.GetCollection<Item>("Items").Find(query).AsQueryable(); 

Come faccio a "aggiungere" qbAttributes-query? Ho provato qbAttributes.And(query); ma .Find(query) errori con un argomento non valido.

ho bisogno di qualcosa che sarebbe come:

var query = Query.And(
    Query.EQ("ItemTypeTemplate", item.ItemTypeTemplate),  //Tablet Screens 
    Query.NE("UsernameOwner", item.UsernameOwner)    //current user 

    // this part is generated by the loop 

    Query.EQ("Attributes.AttributeName", "Screen Size"), 
    Query.EQ("Attributes.AttributeValue", "10.1"), 

    Query.EQ("Attributes.AttributeName", "Pixel Density"), 
    Query.EQ("Attributes.AttributeValue", "340") 
); 

risposta

7

Mentre non testati (come non ho uno scenario simile al tuo per testare con), si dovrebbe essere in grado di aggiungere solo i vari and condizioni una collezione (che implementa IEnumerable) come questo, e quindi passa al metodo della QueryBuilder esempio And:

var andList = new List<IMongoQuery>(); 

foreach (var attribute in item.Attributes) 
{ 
    andList.Add(Query.EQ("Attributes.AttributeName", attribute.AttributeName)); 
    andList.Add(Query.EQ("Attributes.AttributeValue", attribute.AttributeValue)); 
} 

andList.Add(Query.EQ("TemplateId", item.TemplateId)); 
andList.Add(Query.NE("UsernameOwner", item.UsernameOwner)); 

var query = new QueryBuilder<Item>(); 
query.And(andList); 
// do something with query ... 

il codice sopra dovrebbe essere l'equivalente di eseguire un $and su tutte le condizioni specificate.

+0

Fai attenzione agli elementi dell'array e osserva Controlla gli elementi dell'array e guarda http://docs.mongodb.org/manual/reference/projection/elemMatch/. usare 2 "e" termini su una matrice non significa che il nome attr e il valore attr si verificano all'interno dello stesso elemento. –