【问题标题】:Comparing dates in Mongodb with C# LINQ driver将 Mongodb 中的日期与 C# LINQ 驱动程序进行比较
【发布时间】:2016-11-04 13:50:03
【问题描述】:

我有一个 MongoDB 集合,其中包含一个表示日期的字符串字段。在我的 C# 应用程序中,我将结果映射到具有聚合字段的类,该聚合字段将该字符串转换为 DateTime 对象

[BsonIgnoreExtraElements]
public class Tweet
{
    public ObjectId Id { get; set; }

    [BsonElement("text")]
    public string Texto { get; set; }

    [BsonElement("created_at")]
    public string Fecha { get; set; }

    public DateTime FechaConvertida
    {
        get
        {
            var formato = "ddd MMM dd HH:mm:ss zzzz yyyy"; //'Sun Oct 23 19:42:04 +0000 2016'
            var enUS = new CultureInfo("en-US");
            var fechaConvertida = DateTime.ParseExact(this.Fecha, formato, enUS, DateTimeStyles.None);
            return fechaConvertida;
        }
    }
}

然后在我的 api 上查询过滤两个日期之间的元素(使用“CSharp Driver LINQ”)

public IEnumerable<Tweet> GetTweetsDePeriodo(string nombreColeccion, int dias)
    {
        var hoy = DateTime.Today;
        var fechaInicial = hoy.AddDays(-dias);

        var coleccion = _db.GetCollection<Tweet>(nombreColeccion).AsQueryable<Tweet>();
        var tweetsFiltrados = (from c in coleccion
                               where c.FechaConvertida >= fechaInicial
                               select c
                               ).ToList();
        return coleccion;
    }

然后我收到以下错误: *处理请求时发生未处理的异常。 InvalidOperationException: {document}.FechaConvertida 不受支持

有什么想法吗? 提前致谢,

【问题讨论】:

  • 你能将 fechaInicial 声明为 DateTime 而不是 var。
  • 你能告诉我们你的推文数据对象吗?
  • @viveknuna 我试过了,但没有改变任何东西。无论如何,谢谢,
  • @Dudemanword 推文数据对象是一个大 json,实际上它只是返回 Twitter API 的对象。在这种情况下,相关的是在“Created_at”字段中返回的带有日期的字符串的格式,这很奇怪:“Sun Oct 23 19:42:04 +0000 2016”。我认为这是主要问题,因为库无法解析它。感谢您的帮助。

标签: c# mongodb linq


【解决方案1】:

最后,我找到了一个使用自定义序列化程序来处理日期字段的解决方案。这就是它的样子。

我的班级:

[BsonIgnoreExtraElements]
public class Tweet
{
    public ObjectId Id { get; set; }

    [BsonElement("text")]
    public string Texto { get; set; }

    [BsonElement("created_at")]
    [BsonSerializer(typeof(FechaTweetsSerializer))]
    public DateTime Fecha { get; set; }
}

还有我的自定义序列化器:

public class FechaTweetsSerializer : SerializerBase<DateTime>
{

    public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, DateTime value)
    {
        context.Writer.WriteString(value.ToString(CultureInfo.InvariantCulture));
    }

    public override DateTime Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        var fecha = context.Reader.ReadString();
        return ConvertirFecha(fecha);
    }

    private DateTime ConvertirFecha(string fechaFormatoTwitter)
    {
        var formato = "ddd MMM dd HH:mm:ss zzzz yyyy"; //'Sun Oct 23 19:42:04 +0000 2016'
        var enUS = new CultureInfo("en-US");
        var fechaConvertida = DateTime.ParseExact(fechaFormatoTwitter, formato, enUS, DateTimeStyles.None);
        return fechaConvertida;
    }
}

希望它对某人有所帮助。

【讨论】:

    【解决方案2】:

    正如 cmets 中已经提到的,如果您要在模型中将属性声明为日期时间

    [BsonElement("created_at")]
    public DateTime Fecha { get; set; }
    

    那么这应该不是问题。您还可以使用 BsonRepresentation 装饰您的财产,以确保发生正确的(反)序列化

    [BsonRepresentation(BsonType.DateTime)]
    [BsonElement("created_at")]
    public DateTime Fecha { get; set; }
    

    为了执行您的查找,一个简单的解决方案是

    var coleccion = _db.GetCollection<Tweet>(nombreColeccion).Find(x => x.Fecha >= fechaInicial).ToList();
    

    创建一个 c# 属性来将字符串解析为日期,然后在您的过滤器中引用该属性将不起作用,因为转换不是在数据库范围内发生,而是在 c# 代码中发生。如果将日期存储为 DateTime (MongoDb ISODate()) 不是一个选项,您可以查看 Project() 以从字符串中投影转换后的日期,然后执行查询

    【讨论】:

    • 我尝试将该字段声明为 DateTime 并添加了“BsonRepresentation”标签,但它引发了异常:FormatException: String was not Recognized as a valid DateTime问题是存储在 BD 中的字符串具有奇怪的日期时间格式:'Sun Oct 23 19:42:04 +0000 2016'。你知道一种“即时”序列化的方法吗?也许是一个自定义的 Bson 序列化器?感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多