如何使用Datastax c# Driver将c#枚举映射到Cassandra字段

本文关键字:映射 Cassandra 字段 枚举 何使用 Datastax Driver | 更新日期: 2023-09-27 18:17:19

我想保存和检索一个POCO对象,并从Cassandra使用Datastax c#驱动程序。. Net Framework 4.6.1, Datastax c# Driver 3.0.8)

的例子:

public enum DocumentState
{
    New = 0,
    Approved = 1,
    Rejected = 2
}
public class DocumentReadModel
{
    public Guid DocumentId { get; set; }
    public DocumentState State { get; set; }
}
在Cassandra中持久化这个对象的最好方法是什么?

我的方法似乎不起作用。

现在我试着把它保存为int在Cassandra:

create table if not exists documentreadmodel (
        documentid uuid PRIMARY KEY,
        state int);

还使用了Datastax驱动程序提供的映射配置,代码如下:

MappingConfiguration.Global.Define(
    new Map<DocumentReadModel>()
            .TableName("documentreadmodel")
            .PartitionKey(o => o.MerchantId)
            .Column(o => o.State, c =>     c.WithName("state").WithDbType<int>()));

但是我仍然得到一个异常:

Cassandra.InvalidTypeException: 
Unknown Cassandra target type for CLR type ValueObjects.DocumentState

我应该在Cassandra中使用另一种int类型吗?不同地配置驱动程序?

如何使用Datastax c# Driver将c#枚举映射到Cassandra字段

我找到了解决方案,通过更新全局配置来使用For

我正在使用。net 4.5.2 CassandraCSharpDriver 3.3.2

尝试更新您的配置以使用"For"

MappingConfiguration.Global.Define(
For<DocumentReadModel>()
        .TableName("documentreadmodel")
        .PartitionKey(o => o.MerchantId)
        .Column(o => o.State, c => c.WithName("state").WithDbType<int>()));

这是一个相当古老的问题,但可能会帮助其他人遇到这些问题…

要将Enum保存为cassandra,需要定义一个转换器函数将Enum转换为Int。应该是这样的:

public class MyTypeConverter : TypeConverter
{
    protected override Func<TDatabase, TPoco> GetUserDefinedFromDbConverter<TDatabase, TPoco>()
    {
        if (typeof(TDatabase) == typeof(Int32) && typeof(TPoco) == typeof(DocumentState))
        {
            Func<Int32, DocumentState> func = documentState=> (DocumentState)documentState;
            return (Func<TDatabase, TPoco>)(object)func;
        }
        return null;
    }
    protected override Func<TPoco, TDatabase> GetUserDefinedToDbConverter<TPoco, TDatabase>()
    {
        if (typeof(TDatabase) == typeof(Int32) && typeof(TPoco) == typeof(DocumentState))
        {
            Func<Provider, Int32> func = documentState=>
                    ((Int32)documentState);
            return (Func<TPoco, TDatabase>)(object)func;
        }
        return null;
    }
}

那么在定义表时,您应该注册转换器:

        var mapping = new MyMapping();
        var table = new Table<T>(session, new MappingConfiguration()
            .ConvertTypesUsing(new MyTypeConverter())
            .Define(mapping));

当查询cassandra时,驱动程序使用序列化器(而不是TypeConverter),并且它们不支持枚举。所以你必须把Enum替换成Int。我使用LINQ,它看起来像这样:

        int documentStateInt = (int)documentState;
        Expression<Func<DocumentReadModel, bool>> predicate;
        predicate= drm => (int)drm.State == documentStateInt;
        return table.Where(predicate).ExecuteAsync();

*使用驱动程序版本3.16