2016-06-16 15 views
2

Ich habe gerade angefangen mit mongodb in C# und es ist toll, aber ich habe zu kämpfen, um zu verstehen, wie ich dynamisch erstellen konnte eine linq Abfrage an mongodb übergeben.dynamisch erstellen linq mit mongodb

Situation: Ich habe eine Datei mit einigen allgemeinen Eigenschaften Dateiname, Dateigröße ect, eine dieser Eigenschaften ist Metadaten, die eine Liste von Feldern mit Werten ist. Der Benutzer wird in der Lage sein, die Suchkriterien dynamisch festzulegen, und so kann ich diese Abfrage nicht hart codieren.

Mein Objekt auf Vollständigkeit:

public class asset 
{ 
    public ObjectId Id { get; set; } 
    public string filename { get; set; } 
    public int filesize { get; set; } 
    public List<shortmetadata> metadata { get; set; } 
} 

public class shortmetadata 
{ 
    public string id { get; set; } 
    public string value { get; set; } 
} 

Mein aktueller Code, der manuell die Suchkriterien setzt und gibt einen Vermögenswert, die „Hallo“ oder „Welt“ in dem Metadaten Wertfeld hat:

 MongoClient client = new MongoClient(); 
     var db = client.GetDatabase("Test"); 
     var collection = db.GetCollection<asset>("assets"); 

     var assets = collection.AsQueryable().Where(i => 
     i.metadata.Any(m => m.value.Contains("hello")) || 
     i.metadata.Any(m => m.value.Contains("world")) 
     ); 

Was ich gerne tun könnte, ist dynamisch erstellen Sie die Abfrage auf der Grundlage der Benutzer Auswahl (noch nicht, wie es zuerst in Code arbeiten wollen!)

Jede Hilfe wäre großartig.

+0

Sie können die Kette nur die 'Wo (...)' fordert die 'IQueryable' über die Kriterien abhängig und Linq wird sie in einen Ausdruck lösen - oder [wenn man tiefer gehen wollen ..] (https : //www.simple-talk.com/dotnet/.net-framework/giving-clarity-to-linq-queries-by-ext-expressions/) – stuartd

Antwort

0

Wenn Sie zum Beispiel ein Wörterbuch < String hatte, string > den Namen Wert enthält, die für den Namen des Meta-Element verkeilt suchen Sie Ihren IQueryable < Asset-> up in einer Schleife wie diese

bauen könnte
var query = collection.AsQueryable(); 
//Non-meta properties 
query = query.Where(a => a.SomeNonMetaProperty == "Something"); 
//And now meta properties 
foreach(var keyAndValue in someDictionary) 
{ 
    query = query.Where(m => 
    m.Name == keyAndValue.Key 
    && m.Value == keyAndValue.Value; 
} 
0

Slazure können Sie dynamische Linq-Abfragen zur Laufzeit erstellen, da die Prädikate String-Literale sind.

PM> Install-Package Slazure.MongoDB

// C# example: Build a document query that return employees that has a salary greater than $40k/year using a dynamic LINQ query filter. 
dynamic storage = new QueryableStorage<DynDocument>("mongodb://user:[email protected]/MongoDBExample"); 
QueryableCollection<DynDocument> employeesCollection = storage.Employees; 
var employeeQuery = employeesCollection 
    // Query for salary greater than $40k and born later than early '95. 
    .Where("Salary > 40000 and Birthdate >= DateTime(1995,15,3)") 
    // Projection and aliasing. 
    .Select("new(_id as Email, Birthdate, Name, Timestamp as RegisteredDate)") 
    // Order result set by birthdate descending. 
    .OrderBy("Birthdate desc") 
    // Paging: Skip the first 5 and retrieve only 5. 
    .Skip(5).Take(5) 
    // Group result set on Birthdate and then on Name. 
    .GroupBy("Birthdate", "Name"); 

// Use a dynamic type so that we can get access to the document's dynamic properties 
foreach (dynamic employee in employeeQuery) 
{ 
    // Show some information about the employee 
    Console.WriteLine("The employee '{0}' was employed {1} and was born in {2}.", 
     employee.Email, employee.RegisteredDate, employee.Birthdate.Year); 
} 

Es unterstützt auch Werte Substitution, die Ihr Prädikat Code aussehen sauberer macht.

// C# example: Query the storage for employee that earn less than $60k/yr and that are born before the millennium. 
var amount = 60000; 
var employeeQuery = employeesTable.Where("Salary > @0 and Timestamp <= @1", amount, new DateTime(2000, 1, 1));