c# - MongoDocument 对象在查询时仅被部分填充
问题描述
我有一组用户正在尝试从数据库中读取,但由于某种原因,发生了一些我无法弄清楚的奇怪行为。希望有人可以建议或帮助我找到这个问题的根源。
所以基本上,每当我在 HomeController.cs 中调用这段代码时,会发生什么:
var users = await _database.GetCollection<User>("ApplicationUsers").FindAsync(_ => true);
var userList = users.ToList();
它只填充 userList 部分,这意味着只有 ID 和 ConcurrencyStamp 属性被填充,但其他属性总是最终为空(见:https ://i.imgur.com/RTF8ljL.png )
但是每当我在 Startup.cs 中的数据库连接初始化之后添加这一行时:
database.GetCollection<User>("ApplicationUsers");
然后突然 userList 确实填充了所有其他信息(如 https://i.imgur.com/f5IV7fh.png所示)
所以为了让它工作,我必须在连接初始化后立即获取集合,我不太喜欢,因为我不必为其他集合执行此操作。所以我的 mongo 连接代码在 Startup.cs 中必须如下所示:
var mongoUrl = new MongoUrl(config.GetSection("DatabaseSettings:ConnectionString").Value);
var mongoClientSettings = MongoClientSettings.FromUrl(mongoUrl);
mongoClientSettings.ClusterConfigurator = cb => ConfigureCluster(cb);
var client = new MongoClient(mongoClientSettings);
var database = client.GetDatabase(config.GetSection("DatabaseSettings:DatabaseName").Value);
database.GetCollection<User>("ApplicationUsers"); // TODO: This is needed just to let Mongo Driver know to which class to deserialize this collection
services.AddSingleton<IMongoDatabase>(database);
var pack = new ConventionPack()
{
new CamelCaseElementNameConvention(),
new IgnoreExtraElementsConvention(true),
new DictionaryRepresentationConvention(DictionaryRepresentation.ArrayOfArrays)
};
ConventionRegistry.Register("DatabaseConventions", pack, t => true);
我猜在 Startup.cs 和 HomeController.cs 的执行之间发生了导致反序列化混乱的事情?
更新:
同样的行为似乎发生在一个干净的项目上,我安装的唯一 nuget 包是官方的 mongodb 驱动程序和 Matteo Fabbri 的 AspNetCore.Identity.Mongo。当我将 getCollection 用于其他类时,不会发生这种奇怪的反序列化行为。问题在于从 MongoUser 扩展的 ApplicationUser (由 AspNetCore.Identity.Mongo 库提供的类)
更新 2:
原来 AspNetCore.Identity.Mongo 库中的 MongoUser 类对注册的 ConventionPack 过敏。我通过在注册数据库约定之前和之后获取集合来测试这一点。现在为此寻找合适的解决方案。
更新 3:
我还发现文档是用大驼峰大小写命名的属性保存的,这可能是 mongodb 驱动程序混乱的原因。对于这个特定的类(ApplicationUser),似乎将它们保存在 CamelCase 中的约定被忽略了。
解决方案
我设法解决了这个问题。问题是代码执行的顺序。约定包在 MongoIdentity 之后注册并初始化数据库。在初始化 MongoIdentity 和数据库期间,ApplicationUser 被配置为在包中没有 CamelCaseElementNameConvention,这导致类被保存在 UpperCamelCase 中,因此在注册的 ConventionPack 处于活动状态时检索集合时会导致混乱。
对于那些在你认为你的代码应该可以工作的奇怪行为中挣扎的人,请记住代码执行的顺序非常重要,并且很可能是导致该行为的原因。祝大家好运!
推荐阅读
- go - 服务器在返回语句后崩溃
- django - 我的主页出现 NoReverseMatch 错误
- c# - 逻辑处理空值
- node.js - Express-Session 在生产/部署中不起作用
- javascript - 如何使 Node 和 React 应用程序共享类
- python - Python如何在电脑突然关机的情况下保存一个txt文件?
- ffmpeg - FFMpeg 命令输出显示“绿色像素化”视频
- python - 使用 GEKKO 的 ODE 系统中的参数估计
- swift - 在应该将音频从输入设备传递到输出设备的这个 Swift 代码中,0 的对象 id 来自哪里?查看错误信息
- dart - posix setgid() 无法降低权限