2016-06-16 13 views
2

Я только начал использовать mongodb в C#, и это здорово, однако я изо всех сил пытаюсь понять, как я мог динамически создавать запрос linq для перехода к mongodb.динамически создавая linq с mongodb

Ситуация: У меня есть файл, который имеет некоторые общие свойства filename, ectizeizeize, одно из этих свойств - это метаданные, которые представляют собой список полей со значениями. пользователь сможет динамически определять критерии поиска, поэтому я не могу жестко запросить этот запрос.

Мой объект для полноты:

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

Вы можете просто ЦЕПЬ 'Where (...)' звонки на 'IQueryable' в зависимости от критериев и LINQ будет решать их в выражение - или, [если вы хотите пойти глубже ..] (HTTPS : //www.simple-talk.com/dotnet/.net-framework/giving-clarity-to-linq-queries-by-extending-expressions/) – stuartd

ответ

0

Если, к примеру, вы имели строку словарь <, строка >, содержащее значение имени для поиска введенного по имени меты-элемента, который вы могли бы построить свой IQueryable <Asset> в цикле, как это

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

Он также поддерживает подстановочные значения, что делает ваш код предиката взгляд чище.

// 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)); 
Смежные вопросы