編輯3:
好了,它看起來像您現在已經建立了複雜的查詢有代碼。在這種情況下,您只需修復編譯器問題。我假設你要做到以下幾點(x > 20 && x < 40) && (y > 30 && y < 50)
...
var collection = _myDB.GetCollection<MyDocument>("collection");
var queries = new List<IMongoQuery>();
foreach (MyObject queryObj in Queries)
{
//I have several hundred fields such as Height, that are in queryObj
//how do I build a "boolean" query in C#
var lowerBoundQuery = Query.GTE("Height", Convert.ToInt16(queryObj.Height * lowerbound));
var upperBoundQuery = Query.LTE("Height", Convert.ToInt16(queryObj.Height * upperbound));
var query = Query.And(lowerBoundQuery, upperBoundQuery);
queries.Add(query);
}
var finalQuery = Query.And(queries);
/*
if you want to instead do an OR,
var finalQuery = Query.Or(queries);
*/
原來的答覆。
var list = _myDb.GetCollection<MyDoc>("CollectionName")
.AsQueryable<MyDoc>()
.Where(x =>
x.Height > 20 &&
x.Height < 40)
.ToList();
我曾嘗試使用的示例Query.GT( 「場」,值1).LT(值2);, 但是編譯器不接受LT(值)構建體。
如果您使用官方的C#驅動程序,您可以使用linq查詢MongoDB。這應該解決我認爲的編譯器問題。
我想到的更有趣的問題是,你將如何構造複雜的布爾查詢?
一種選擇是動態建立一個Expression
,然後傳遞到Where
我的同事正在使用類似的東西,下面的代碼...
public static IQueryable<T> Where<T>(this IQueryable<T> query,
string column, object value, WhereOperation operation)
{
if (string.IsNullOrEmpty(column))
return query;
ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
MemberExpression memberAccess = null;
foreach (var property in column.Split('.'))
memberAccess = MemberExpression.Property
(memberAccess ?? (parameter as Expression), property);
//change param value type
//necessary to getting bool from string
ConstantExpression filter = Expression.Constant
(
Convert.ChangeType(value, memberAccess.Type)
);
//switch operation
Expression condition = null;
LambdaExpression lambda = null;
switch (operation)
{
//equal ==
case WhereOperation.Equal:
condition = Expression.Equal(memberAccess, filter);
lambda = Expression.Lambda(condition, parameter);
break;
//not equal !=
case WhereOperation.NotEqual:
condition = Expression.NotEqual(memberAccess, filter);
lambda = Expression.Lambda(condition, parameter);
break;
//string.Contains()
case WhereOperation.Contains:
condition = Expression.Call(memberAccess,
typeof(string).GetMethod("Contains"),
Expression.Constant(value));
lambda = Expression.Lambda(condition, parameter);
break;
}
MethodCallExpression result = Expression.Call(
typeof(Queryable), "Where",
new[] { query.ElementType },
query.Expression,
lambda);
return query.Provider.CreateQuery<T>(result);
}
public enum WhereOperation
{
Equal,
NotEqual,
Contains
}
目前,它僅支持==
& & !=
,但它應該不是那麼難實施>=
或<=
...
你可以從表達式類得到一些提示:http://msdn.microsoft.com/en-us/library/system.linq.expressions.expression.aspx
編輯:
var props = ["Height", "Weight", "Age"];
var query = _myDb.GetCollection<MyDoc>("CName").AsQueryable<MyDoc>();
foreach (var prop in props)
{
query = query.Where(prop, GetLowerLimit(queryObj, prop), WhereOperation.Between, GetUpperLimit(queryObj, prop));
}
// the above query when iterated over, will result in a where clause that joins each individual `prop\condition` with an `AND`.
// The code above will not compile. The `Where` function I wrote doesnt accept 4 parameters. You will need to implement the logic for that yourself. Though it ought to be straight forward I think...
編輯2:
如果你不想使用LINQ,你仍然可以使用Mongo查詢。您只需要使用Query.And()
和Query.Or()
來製作您的查詢。
// I think this might be deprecated. Please refer the release notes for the C# driver version 1.5.0
Query.And(Query.GTE("Salary", new BsonDouble(20)), Query.LTE("Salary", new BsonDouble(40)), Query.GTE("Height", new BsonDouble(20)), Query.LTE("Height", new BsonDouble(40)))
// strongly typed version
new QueryBuilder<Employee>().And(Query<Employee>.GTE(x => x.Salary, 40), Query<Employee>.LTE(x => x.Salary, 60), Query<Employee>.GTE(x => x.HourlyRateToClients, 40), Query<Employee>.LTE(x => x.HourlyRateToClients, 60))
嗨,感謝您的回覆,但我如何建立一個範圍列表例如Where(x => x.Height> 20 && x.Height < 40), y => y.Height> 30 && y.Height <60)等等。 – Mikos 2012-07-26 11:51:01
最好是否有非LINQ方式?或者是LINQ我唯一的選擇? – Mikos 2012-07-26 11:53:21
編輯是否有幫助? .. Cuz,老實說,我不明白你在評論中寫的「Where」的例子。它不會編譯。 'Where'不接受'x'和'y'兩個參數... – 2012-07-26 12:07:01