关于mongodb.net驱动程序:C#中列表索引中的-1

-1 in the index of a list in C#

我最近在我们的应用程序中遇到了下面这段代码

1
2
var updateDefinition = new UpdateDefinitionBuilder<OverviewProfile>()
            .Set(a => a.Advisors[-1].IsCurrent, advisor.IsCurrent);

在上面的代码中,AdvisorsListUpdateDefinitionBuilder来自mongodb驱动程序。

你能告诉我清单索引中-1的用法吗?

在以下评论/答案之后编辑

OverviewProfile类如下:

1
2
3
4
5
6
7
8
9
10
public class OverviewProfile: BaseInvestorProfile
{
    //Other properties

    public List<Advisor.View.Advisor> Advisors { get; set; }
    public OverviewProfile(int id): base(id)
    {
        Advisors = new List<Advisor.View.Advisor>();
    }
}

这就是工作代码。此代码根据条件将数据更新到mongo db。这个类中没有其他方法,只有其他属性。

这是一个类,但是对于多个类的属性也有相同的用法,即使我们添加一个新的List属性并进行检查,它也可以正常工作。


您使用的是预期的ExpressionUpdateDefinitionBuilder.Set的过载。此表达式不是直接编译和执行的,而是转换为本机MongoDB语法,并用作MongoDB查询的一部分(与Entity Framework或其他ORM将表达式转换为SQL的方式相同)。这基本上是说"更新所有概述配置文件并设置第一个顾问的iscurrent标志,该标志与advisor.IsCurrent值匹配"。因为mongodb允许负索引(意思是相对于集合的结尾),所以c mongodb驱动程序可以将表达式转换为有效的mongodb查询(但请参见下面的更新)。

更新。如本文所述,-1对于MongoDB C驱动程序仍然有特殊意义。它将转换为位置更新运算符$:

the positional $ operator acts as a placeholder for the first element
that matches the query document

例如:

1
2
3
4
var updateDefinition = new UpdateDefinitionBuilder<OverviewProfile>()
    .Set(a => a.Advisors[-1].IsCurrent, false);

colleciton.UpdateOne(c => c.Advisors.Any(r => r.IsCurrent), updateDefinition);

将被转换为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
"updates": [{
       "q": {
           "Advisors": {
               "$elemMatch": {
                   "IsCurrent": true
                }
            }
        },
       "u": {
           "$set": {
               "Advisors.$.IsCurrent": false // <- your expression
            }
        }
    }
]

但是,关于MongoDB中相对于收集结束的负索引含义的观点仍然成立,因为除-1(例如,-2)之外的任何其他负索引都将转换为如下查询:

1
{"$set" : {"Advisors.-2.IsCurrent" : false} }


如果a.Advisors确实是List的话,就没有用了。那会扔下一个江户。

更可能的是,这是在List上的一些自定义类或实现,其中传递给索引器的-1值意味着类似于"默认"值。

不管是什么,我认为这是一个糟糕的设计,应该避免。