如何使用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类型吗?不同地配置驱动程序?
我找到了解决方案,通过更新全局配置来使用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