将DateTime保存到Cassandra Date列 - c#

Cassandra .NET驱动程序文档令人难以置信的糟糕,我试图将某些功能拼凑在一起,但我浪费大量时间试图从发现的Java文档中更改代码。

我正在尝试使用Cassandra驱动程序将数据写入一个简单的表。该表已经存在,并且里面有日期。我创建了一个映射并添加了一些列。这是演示的简化版本:

For<Profile>().TableName("profiles")
    .PartitionKey(p => p.IntegerId)
    .Column(p => p.IntegerId, cm => cm.WithName("profileid"))
    .Column(p => p.BirthDate, cm => cm.WithName("dateofbirth"))

列和表还有更多,但这是重要的部分。

然后通过一个简单的通用方法完成保存:

public async Task<bool> Add<T>(T item) where T : EntityBase, new()
{
    await _mapper.InsertIfNotExistsAsync(item);
}

同样,这里还有更多代码,但是相关的部分在这里。重要的是我正在使用InsertIfNotExists并使用与基本实体一起使用的通用方法。

Cassandra中的dateofbirth列的类型为Date。
当我运行Insert方法时,我得到一个例外,即Date的长度应该是4个字节而不是8个字节(我假设我需要切断DateTime的时间部分)。

我尝试在映射上使用WithType并创建与this question中所述类似的TypeSerializer,但是没有运气。
任何人都有可以将这种类型(可能还有其他类型)保存到Cassandra的有效代码吗?

这是从互联网改编的日期编解码器的代码,以及如何使用它,这可能是(非常)错误的:

public class DateCodec : TypeSerializer<DateTime>
{
    private static TypeSerializer<LocalDate> _innerSerializer;

    public DateCodec(TypeSerializer<LocalDate> serializer)
    {
        _innerSerializer = serializer;
        TypeInfo = new CustomColumnInfo("LocalDate");
    }

    public override IColumnInfo TypeInfo { get; }

    public override DateTime Deserialize(ushort protocolVersion, byte[] buffer, int offset, int length, IColumnInfo typeInfo)
    {
        var result = _innerSerializer.Deserialize(protocolVersion, buffer, offset, length, typeInfo);
        return new DateTime(result.Year, result.Month, result.Day);
    }

    public override ColumnTypeCode CqlType { get; }

    public override byte[] Serialize(ushort protocolVersion, DateTime value)
    {
        return _innerSerializer.Serialize(protocolVersion, new LocalDate(value.Year, value.Month, value.Day));
    }
}

用法:

TypeSerializerDefinitions definitions = new TypeSerializerDefinitions();
definitions.Define(new DateCodec(TypeSerializer.PrimitiveLocalDateSerializer));

var cluster = Cluster.Builder()
    .AddContactPoints(...)
    .WithCredentials(...)
    .WithTypeSerializers(definitions)
    .Build();

参考方案

C#驱动程序使用LocalDate类来表示Cassandra中的date,因此需要更改您的dateofbirth声明以使用它,或开发相应的编解码器。

您可以查看有关C#驱动程序的日期和时间表示形式的文档:https://docs.datastax.com/en/developer/csharp-driver/3.5/features/datatypes/datetime/

使用代码示例更新问题后进行更新:

定义表并插入样本数据:

cqlsh> create table test.dt(id int primary key, d date);
cqlsh> insert into test.dt(id, d) values(1, '2018-05-17');
cqlsh> insert into test.dt(id, d) values(2, '2018-05-16');
cqlsh> insert into test.dt(id, d) values(3, '2018-05-15');

以下对我有用的转换作品:

public class DateCodec : TypeSerializer<DateTime>
{
    private static readonly TypeSerializer<LocalDate> serializer = 
         TypeSerializer.PrimitiveLocalDateSerializer;

    public override ColumnTypeCode CqlType
    {
        get { return ColumnTypeCode.Date; }
    }

    public DateCodec() { }

    public override DateTime Deserialize(ushort protocolVersion, byte[] buffer, 
         int offset, int length, IColumnInfo typeInfo)
    {
        var result = serializer.Deserialize(protocolVersion, buffer,
                offset, length, typeInfo);
        return new DateTime(result.Year, result.Month, result.Day);
    }

    public override byte[] Serialize(ushort protocolVersion, DateTime value)
    {
        return serializer.Serialize(protocolVersion, 
            new LocalDate(value.Year, value.Month, value.Day));
    }
}

主程序:

TypeSerializerDefinitions definitions = new TypeSerializerDefinitions();
definitions.Define(new DateCodec());

var cluster = Cluster.Builder()
         .AddContactPoints("localhost")
         .WithTypeSerializers(definitions)
         .Build();
var session = cluster.Connect();
var rs = session.Execute("SELECT * FROM test.dt");
foreach (var row in rs)
{
    var id = row.GetValue<int>("id");
    var date = row.GetValue<DateTime>("d");
    Console.WriteLine("id=" + id + ", date=" + date);
}

var pq = session.Prepare("insert into test.dt(id, d) values(?, ?);");
var bound = pq.Bind(10, new DateTime(2018, 04, 01));
session.Execute(bound);

结果如下:

id=1, date=5/17/18 12:00:00 AM
id=2, date=5/16/18 12:00:00 AM
id=3, date=5/15/18 12:00:00 AM

并从cqlsh检查:

cqlsh> SELECT * from test.dt ;

 id | d
----+------------
 10 | 2018-04-01
  1 | 2018-05-17
  2 | 2018-05-16
  3 | 2018-05-15

Python 3运算符>>打印到文件 - python

我有以下Python代码编写项目的依赖文件。它可以在Python 2.x上正常工作,但是在使用Python 3进行测试时会报告错误。depend = None if not nmake: depend = open(".depend", "a") dependmak = open(".depend.mak&#…

如何以编程方式扩展Jquery Slider Panel? - c#

我有用于登录的JQuery Silder面板|注册选项。供参考,我已包含此滑块Jquery Login | Register Slider Panel的演示实际的问题是,当位于“文字”控件中的“登录”部分或“注册新帐户”部分中有值时,如何以编程方式扩展此滑块。为了理解这个问题,我把我的设计代码。 <asp:Panel ID="Panel_Lo…

无法解析Json响应 - php

我正在尝试解析一个包含产品类别的JSON文件,然后解析这些类别中的产品,并在div中显示它们。我的问题:虽然我可以获取类别,但我不知道如何索取产品(并将它们显示在类别下)。我的剧本:<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> …

在xpath中选择多个条件 - php

我正在尝试使用来自高尔夫比赛的xml提要,以显示每个高尔夫球手在高尔夫球场上的位置。目前,我想展示符合两个条件的所有高尔夫球手(排在前25名,以及所有加拿大高尔夫球手)。这是xml提要的示例。<GolfDataFeed Type="Leaderboards" Timestamp="3/21/2012 9:18:09 PM&…

Json到php,json_decode返回NULL - php

我正在用PHP进行JSON解析器的一些API,用于存储有关遗产的信息。我在解析时遇到问题,因为它返回的是NULL值而不是数组或对象。简单的JSON代码可以很好地解析,但是可以这样:{"success":true,"totalCount":1,"data":[{"id":99694…