0

使用 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# 提供程序。

4

2 回答 2

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将检查数组中的单个元素是否匹配所有条件。在这种情况下,数组元素只有一个条件,这是同一件事,但不是同一个查询。

于 2013-09-02T22:46:56.667 回答
0

根据@mnemosyn 的回答,我想出了通过添加向下转换来改进的解决方案。

经过大量输入后,我首先使用了 ElemenMatch,但在对 stackoverflow 进行了进一步搜索后,我发现了从 IQueryable 到 MongoQueryable 的向下转换,如此处所述

将 Queryable<T> 翻译回 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();

真的很棒。

于 2013-09-09T21:44:16.833 回答