我正在尝试使用另一个对象(MyObject)上的属性值更新对象数组中每个对象的属性。我不清楚是否打电话:
my_objects_collection = m_database.GetCollection(MY_OBJECTS_COLLECTION_NAME);
有任何性能影响,所以我尝试只调用一次并在For ... Loop中对它执行一个新的Find命令(每次迭代都有一个修改过的过滤器),见下文:
MyObject my_object = null;
IMongoCollection<MyObject> my_objects_collection = null;
if (objects != null)
{
my_objects_collection = m_database.GetCollection<MyObject>(MY_OBJECTS_COLLECTION_NAME);
for (int i = 0; i < objects.Count; i++)
{
Expression<Func<MyObject, bool>> filter = x => (x.ID == objects[i].ID) && (x.LanguageCode == language_code);
my_object = await my_objects_collection.Find(filter).FirstOrDefaultAsync();
if (my_object != null)
{ objects[i].DisplayName = my_object.Name; }
}
}
但是,上面的代码会抛出以下异常:
值不能为空。 参数名称:集合
在MongoDB.Driver.Core.Misc.Ensure.IsNotNull [T](T值,String paramName)
在MongoDB.Driver.IMongoCollectionExtensions.Find [TDocument](IMongoCollection 1 collection, Expression
1过滤器,FindOptions选项)
如果我在for循环中移动my_objects_collection赋值,以便为每次迭代调用它,代码就可以运行而不会抛出任何异常。
因此我的问题是,对其执行查找(或任何其他操作)后,MongoCollection引用(my_objects_collection)会发生什么?
如果有人能对此提供一些见解,我真的很感激。我可以继续,因为我的应用程序正在运行,但我真的想知道为什么它抛出一个异常,表明该集合为我自己的理解为空。
提前谢谢你,
安德鲁
答案 0 :(得分:1)
无论您的异常如何,您都不需要为检索的每条记录执行查找,您可以使用$ in运算符来实现此目的。
然后,您可以循环结果集并对每个文档执行更新。这样做效率要高得多,因为您要对数据库执行单个操作以返回记录,然后为每个更新执行一个操作。而不是每个检索一个,每个更新一个。
见
Builders<MyObject>.Filter.In
此外,如果要匹配嵌入式阵列中的元素,可以使用
Builders<MyObject>.Filter.ElemMatch
快速(未经测试)的例子
if (objects != null)
{
var my_objects_collection = m_database.GetCollection<MyObject>(MY_OBJECTS_COLLECTION_NAME);
var filterBuilder = Builders<MyObject>.Filter;
var inFilter = filterBuilder.In(x => x.ID, objects.Select(x => x.ID));
var andFilter = filterBuilder.And(
inFilter,
filterBuilder.Eq(x => x.LanguageCode, language_code)
);
var results = await my_objects_collection.Find(andFilter).ToListAsync();
foreach(var result in results)
{
//result is going to the a database object returns which matched your filter
}
}