自动本地日期转换为字符串cassandradriver

brtdzjyr  于 2021-06-09  发布在  Cassandra
关注(0)|答案(1)|浏览(356)

我在cassandra和c#中有一个具有一系列属性的模型,因此为了防止自己不得不手动分配一个普通的准备语句(或为我执行该操作的脚本)中的每个值,我开始使用mapper组件。然而,cql date 自动Map到 LocalDate 序列化为具有日期、月份和年份属性的json对象,我需要一个普通字符串。
我看了一眼 MappingConfiguration.Global 哪个有 Define 以及 ConvertTypesUsing 方法,但第一种方法似乎没有我想要的,我甚至无法实现 TypeConverter 类,因为它的语法是我从未见过的(我甚至不知道它是否起作用)。
所以我想知道,Cassandra有没有什么内置的选项来实现我想要的?
如果有人想看看我的定制typeconverter,我认为这是可行的:

using System;
using Cassandra;
using Cassandra.Mapping.TypeConversion;

namespace Api.Helpers
{
    public class LocalDateConverter : TypeConverter
    {
        protected override Func<TDatabase, TPoco> GetUserDefinedFromDbConverter<TDatabase, TPoco>()
        {
            Func<LocalDate, string> converter = date => 
                String.Format("{0}-{1}-{2}", date.Year, date.Month, date.Year);
            return converter;
        }

        protected override Func<TPoco, TDatabase> GetUserDefinedToDbConverter<TPoco, TDatabase>()
        {
            throw new NotImplementedException();
        }
    }

使用这种方法声明语法,我不知道应该在哪里指示我希望转换器应用什么类型。此代码失败 Can't convert 'System.Func<Cassandra.LocalDate, string>' into 'System.Func<TDatabase, TPoco>' .
另一个与cassandra驱动程序无关的解决方案是自定义json转换器,但我也使用odata,它使用自定义序列化程序。

voj3qocg

voj3qocg1#

试试这个:

public class CustomTypeConverter : TypeConverter
{
    protected override Func<TDatabase, TPoco> GetUserDefinedFromDbConverter<TDatabase, TPoco>()
    {
        if (typeof(TDatabase) == typeof(LocalDate) && typeof(TPoco) == typeof(string))
        {
            Func<LocalDate, string> func = date => date?.ToString();
            return (Func<TDatabase, TPoco>) (object) func;
        }

        return null;
    }

    protected override Func<TPoco, TDatabase> GetUserDefinedToDbConverter<TPoco, TDatabase>()
    {
        if (typeof(TDatabase) == typeof(LocalDate) && typeof(TPoco) == typeof(string))
        {
            Func<string, LocalDate> func = dateStr => dateStr == null ? null : LocalDate.Parse(dateStr);
            return (Func<TPoco, TDatabase>) (object) func;
        }

        return null;
    }
}

您可以通过 MappingConfiguration 对象:

var mc = new MappingConfiguration().ConvertTypesUsing(new CustomTypeConverter());

// LINQ
var table = new Table<Poco>(session, mc);

// Mapper
var mapper = new Mapper(session, mc);

要使其工作,您必须将属性类型更改为 string 告诉司机属性Map到 LocalDate 列:

public class Poco
{
    [Cassandra.Mapping.Attributes.PartitionKey]
    [Cassandra.Mapping.Attributes.Column("project_type", Type = typeof(int))]
    public ProjectType ProjectType { get; set; }

    [Cassandra.Mapping.Attributes.Column("date", Type = typeof(LocalDate))]
    public string Date { get; set; }
}

如果不使用基于属性的配置,则如下所示:

var mc = new MappingConfiguration()
            .ConvertTypesUsing(new CustomTypeConverter())
            .Define(
                new Map<Poco>()
                    .PartitionKey(s => s.ProjectType)
                    .Column(s => s.ProjectType, c => c.WithName("project_type"))
                    .Column(s => s.Date, c => c.WithDbType<LocalDate>()));

您还需要在本文档中定义Map MappingConfiguration 示例而不是 MappingConfiguration.Global (除非您使用的是基于属性的配置)。
一定要用同样的 MappingConfiguration 示例,而不是创建多个示例,因为这是驱动程序存储生成的准备语句的地方。

相关问题