使用C#和mongo我正在检查一些不同的查询方法。目前我有一系列旅行,每次旅行都有一系列费用。每次开支都有自己的objectId。
首先,我有了这个查询来查找要更新的特定查询。诀窍是第二部分,我在那里点了费用的ID。
var Update = Query.And(
Query<Trip>.EQ(t => t.Id, ObjectId.Parse(tripId)),
Query<Expense>.EQ( "Expenses._id", ObjectId.Parse(id)));
因为我在这里做了一个拼写错误,并用资本命名为Expenses._Id我正在寻找一种摆脱“松散字符串”的方法。
我试过这个
var tripToUpdate = Query.And(
Query<Trip>.EQ(t => t.Id, ObjectId.Parse(tripId)),
Query<Expense>.EQ(e => e.Id, ObjectId.Parse(id)));
但它已被翻译成
{ "$and" : [{ "_id" : ObjectId("5224f0208c74943810d333f6") },
{ "_id" : ObjectId("5224f0488c74943810d333f7") }] }
而不是预期的Expense._id
。我想我需要某种约定来支持这一点。
是否可以以更强类型的方式编写它,而不仅仅是查询?
对于查询,我已经在使用std C#提供程序了。
答案 0 :(得分:0)
是的,类似是可能的,它不会创建相同的查询,但对于给出的查询,它没有什么区别:
var query =
from c in collection.AsQueryable<Trip>()
where c.Id == trip.Id
where c.Expenses.Any(p => p.Id == myId)
select c;
或
var query =
collection.FindAs<Trip>(
Query.And(
Query<Trip>.EQ(p => p.Id, trip.Id),
Query<Trip>.ElemMatch(p => p.Expenses, q => q.EQ(x => x.Id, myId))));
但请注意,两者都会创建一个$elemMatch
查询,如下所示:
{
"_id" : ObjectId("522512c5298f241198548b9d"),
"Expenses" : {
"$elemMatch" : {
"_id" : ObjectId("522512c5298f241198548b9b")
}
}
elemMatch
将检查数组中的一个元素是否匹配 all 条件。在这种情况下,数组元素只有一个条件,那是相同的,但它不是同一个查询。
答案 1 :(得分:0)
根据@mnemosyn的回答,我想通过添加一个向下转换来改进这个解决方案。
在输入结果之后我最终使用了ElemenMatch,但经过对stackoverflow的进一步搜索后,我发现了从IQueryable到这里提到的MongoQueryable的向下转发
Translate Queryable<T> back to IMongoQuery
此后代码如下:
var query =
.Trips.AsQueryable()
.Where(c => c.Id == ObjectId.Parse(tripId) && c.Expenses.Any(p => p.Id == ObjectId.Parse(id)));
随后向MongoQuery转发
var mongoQuery = ((MongoQueryable<Trip>) query).GetMongoQuery();
工作真的很棒。