因此,我正在执行 SelectMany 查询来迭代集合中对象内部的列表。这是我的查询:
var collection = _database.GetCollection<VehicleDataUpload>(VehiclesCollection);
var aggregation = collection.AsQueryable()
.SelectMany(v => v.VehicleEntries)
.Where(i => Convert.ToInt32(i.PostFlashDTCs) > 0)
.ToList();
但是,每次运行此命令时都会出现以下错误:
MongoDB.Driver.dll 中发生了“System.InvalidOperationException”类型的第一次机会异常
我认为问题与转换函数有关,所以我将其更改为:
.Where(i => Convert.ToInt32("1") > 0)
而且效果仍然很好。我的同事说转换字符串 0 时可能会卡住,但是当我在
"0"
中进行硬编码时,它仍然有效。由于某种原因,它无法转换类字段。我已将该字段设置为字符串,甚至为其设置了默认值:
public class VehicleEntry
{
[BsonElement("PostFlashDTCs")]
[BsonDefaultValue("0")]
public String PostFlashDTCs { get; set; }
}
当我从对象本身读取时,它显示 InvalidFormatException 的原因是什么?
编辑
我编写了一个快速的 for 循环来迭代(在删除 where 步骤之后)并打印是否存在无法转换为整数的字符串。控制台上没有打印任何内容:
foreach (VehicleEntry vehicle in aggregation1)
{
int result;
if (!Int32.TryParse(vehicle.PostFlashDTCs, out result))
{
Console.WriteLine("Bad value!");
}
}
编辑2
我对查询进行了一些限制,以便从只有 12 个 VehicleEntry 元素的案例中提取。之后我放置了一个调试器(我暂时删除了 where 情况)并检查了所有 12 个元素,它们都具有 PostFlashDTCs 字段的有效数字字符串,因此问题在于转换函数,而不是无效字符串。
编辑3
如果我无法在 LINQ 查询中使用
Convert.ToInt32
,为什么当我对字符串值进行硬编码时它会正常工作?编译器是否做了一些奇怪的事情来优化该代码?我不知道这样的优化,但我认为这是可能的。
mongo 驱动程序采用构建为表达式树的 linq 表达式,并将其转换为 Mongo 自己的本机查询语言。错误的原因是它不知道如何转换Convert.ToInt32。
.ToList() 部分强制查询在 Mongo 上运行,之后 linq 语句将在应用程序中运行,并且您将能够在 .ToList 之后使用 Convert.ToInt32。
您也许可以使用强制转换 (https://jira.mongodb.org/browse/CSHARP-900) 所以...
.Where(i => (int)i.PostFlashDTCs > 0)
如果没有向 Mongo 团队提票。
所以...我有点陷入兔子洞的深处了。
如果您转到
MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToPipelineTranslators.ExpressionToPipelineTranslator
,您将看到 Mongo.Driver
能够将哪些方法转换为 Mongo 查询。尽管 Parse
是其中之一,但它仅解析为 DateTime
(MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.MethodTranslators.ParseMethodToAggregationExpressionTranslator
):
public static AggregationExpression Translate(TranslationContext context, MethodCallExpression expression)
{
if (expression.Method.Is(DateTimeMethod.Parse))
{
return TranslateDateTimeParse(context, expression);
}
throw new ExpressionNotSupportedException(expression);
}
我的解决方案是使用
CompareTo
而不将 string
解析为 int
,而是将 int
常量转换为 string
:
var aggregation = collection.AsQueryable()
.SelectMany(v => v.VehicleEntries)
.Where(i => i.PostFlashDTCs.CompareTo("0") > 0)
.ToList();