使用mongodb版本3.4.3,c#驱动程序(nuget MongoDb.Driver)版本2.4.3
给定一个类Amount
的字段decimal
的类,以及此类型的mongodb集合。查询数量大于或小于某个值的条目的集合会产生不正确的结果。将类型更改为' int'时,代码行为正确。在MongoDb中使用十进制字段时是否存在一些问题?
下面的示例代码说明了这个问题。
class C
{
public int Id { get; set; }
public string Description { get; set; }
public decimal Amount { get; set; }
}
// assumes a locally installed mongodb
var connectionstring = "mongodb://localhost:27017/test";
var mongo = new MongoClient(connectionstring);
var db = mongo.GetDatabase("test");
db.DropCollection("testcollection");
db.CreateCollection("testcollection");
var collection = db.GetCollection<C>("testcollection");
// populate with 2 instances (amount 1 and amount 10)
collection.InsertMany(new[]
{
new C{Id = 1, Description = "small", Amount = 1},
new C{Id = 2, Description = "large", Amount = 10},
});
// verify that the documents are indeed persisted as expected
var all = collection.AsQueryable().ToList();
Debug.Assert(all.Count == 2);
Debug.Assert(all[1].Amount == 10);
// the assert below inexplicably fails (the query returns no results)
var largerThan5 = collection.AsQueryable().Where(c => c.Amount > 5).ToList();
Debug.Assert(largerThan5.Count == 1);
答案 0 :(得分:6)
那是因为它会将所有小数转换为字符串(因此它们将存储在mongo数据库的字符串列中)。当然,在这种情况下,您的gt
比较将失败。关于这个问题有一个非常古老的问题here,因为&#34;按预期工作&#34;关闭。据我所知 - 在那些时候没有十进制BSON类型,所以行为是合理的。
现在here您可以看到版本3.4中有新的十进制BSON类型,实际上C#驱动程序已经支持它。但是,如果您只使用.NET decimal
类型 - 它仍会将其转换为字符串,即使使用mongo 3.4也是如此。
你需要做什么(因为你正在运行3.4)是:
使用Amount
:
[BsonRepresentation(BsonType.Decimal128)]
class C
{
public int Id { get; set; }
public string Description { get; set; }
[BsonRepresentation(BsonType.Decimal128)]
public decimal Amount { get; set; }
}
将功能兼容性版本设置为3.4,因为早期版本无法按照规定的here处理BSON十进制:
db.adminCommand({setFeatureCompatibilityVersion: "3.4"})
之后,您的小数将被正确映射,查询将按预期工作。