MongoDB - 使用C#驱动程序

时间:2016-03-05 20:33:10

标签: c# mongodb

您好我想在MongoDB中使用C#驱动程序查找两个日期(时间)之间的条目,但我使用的Find + Filter方法忽略时间并仅按日期搜索(我认为)。我做错了什么?

我的POCO:

public class TestClassForMongo
{
    public ObjectId Id { get; set; }
    public DateTime CreatedDateUtc { get; set; }
    public string Message { get; set; }
}

我的搜索代码:

IMongoCollection<TestClassForMongo> collection = db.GetCollection<TestClassForMongo>("mongoTest");

var filterBuilder = Builders<TestClassForMongo>.Filter;
var filter = filterBuilder.Gt("CreatedDateUtc", new DateTime(2016, 03, 04, 21, 0, 0)) &
             filterBuilder.Lt("CreatedDateUtc", new DateTime(2016, 03, 04, 22, 0, 0));
List<TestClassForMongo> searchResult = collection.Find(filter).ToList();

上面的代码返回空数组,尽管如此:

collection.Find(filterBuilder.Empty).First().CreatedDateUtc

返回日期:“2016-03-04 21:21:54”

MongoDB 3.2.3,C#MongoDB驱动程序2.2.3

驱动程序文档:https://docs.mongodb.org/getting-started/csharp/query/

回答:

我没有提供足够的信息让任何人回答这个问题,问题是时区和UTC相关问题,也是非常基本的问题。我使用DateTime.UtcNow将日期存储在数据库中。它存储为"CreatedDateUtc" : ISODate("2016-03-04T21:21:54.836Z")。在C#中获取此值将返回一个实际上是UTC日期的日期(Kind属性为UTC),其中btw由db中值的“Z”后缀表示。将此UTC日期与新的DateTime()进行比较没有太大意义,因为后者在您的时区中创建了一个日期,该日期可能与+0(UTC)不同。

因此,一个选项是为此过滤器创建日期:

 new DateTime(2016, 03, 04, 21, 0, 0).ToUniversalTime()

或修改小时部分以适应时区差异,在我的示例中,它将增加1小时(因为我在+1时区)。

实际上,我所在的时区存储的时间是22:21:54。如果我使用在我的时区创建的日期在22:00:00和23:00之间进行搜索,我会得到正确的结果。

1 个答案:

答案 0 :(得分:3)

在dateTime字段上添加BSON属性(见下文),

您可以使用linqu语法来构建此类查询

    var min = new DateTime(2016, 03, 03, 22, 0, 0);
    var max = (new DateTime(2016, 03, 03, 23, 0, 0));
    List<TestClassForMongo> searchResult = collection.Find( 
                x => x.CreatedDateUtc > min &
                x.CreatedDateUtc < max
                ).ToList();
  

BSON ATTRIBUTE

public class TestClassForMongo
{
    public ObjectId Id { get; set; }

    [BsonDateTimeOptions]
    public DateTime CreatedDateUtc { get; set; }

    public string Message { get; set; }
}
  

下面的linqPad转储:

linqPad dump