2016-06-16 75 views
2

我剛剛開始在c#中使用mongodb,但它很好,但我很努力去理解如何動態地創建一個linq查詢來傳遞給mongodb。用mongodb動態創建linq

情況:我有一個文件具有一些常規屬性文件名,文件大小等,其中一個屬性是元數據,它是具有值的字段列表。用戶將能夠動態地指定搜索條件,所以我不能硬編碼這個查詢。

我給完整性對象:

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; } 
} 

我當前的代碼,其被手動設置的搜索條件,並返回具有「你好」或「世界」,在元數據值字段中的任何資產:

 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")) 
     ); 

我希望能夠做的是動態地創建基於用戶選擇的查詢(不要這樣做,因爲想讓它在代碼中工作!)

任何幫助都會很棒。

+0

您只需鏈'在哪裏(...)'的'取決於標準和LINQ將他們解決到表達IQueryable'電話 - 或者,[如果你想更深入..](HTTPS ://www.simple-talk.com/dotnet/.net-framework/giving-clarity-to-linq-queries-by-extending-expressions/) – stuartd

回答

0

如果,例如,你有一個字典<字符串,字符串>包含名稱值來搜索由元項目,你可以建立自己的IQueryable <資產>了在一個循環中這樣

名稱鍵控
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允許您在運行時創建動態Linq查詢,因爲它的謂詞是字符串文字。

PM>安裝,包裝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); 
} 

它還支持,讓您的謂詞的代碼看起來更清潔替代值。

// 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));