2025-04-17 20:28:50 +08:00

89 lines
3.3 KiB
C#

using System.Reflection;
using System.Text;
using Cassandra;
using System.ComponentModel.DataAnnotations;
using JiShe.CollectBus.Common.Attributes;
using Cassandra.Mapping;
using Cassandra.Data.Linq;
using Thrift.Protocol.Entities;
namespace JiShe.CollectBus.Cassandra.Extensions
{
public static class SessionExtension
{
public static void CreateTable<TEntity>(this ISession session,string? defaultKeyspace=null) where TEntity : class
{
var type = typeof(TEntity);
var tableAttribute = type.GetCustomAttribute<CassandraTableAttribute>();
var tableName = tableAttribute?.Name ?? type.Name.ToLower();
//var tableKeyspace = tableAttribute?.Keyspace ?? defaultKeyspace;
var tableKeyspace = session.Keyspace;
var properties = type.GetProperties();
var primaryKey = properties.FirstOrDefault(p => p.GetCustomAttribute<KeyAttribute>() != null);
if (primaryKey == null)
{
throw new InvalidOperationException($"No primary key defined for type {type.Name}");
}
var cql = new StringBuilder();
cql.Append($"CREATE TABLE IF NOT EXISTS {tableKeyspace}.{tableName} (");
foreach (var prop in properties)
{
var ignoreAttribute = prop.GetCustomAttribute<CassandraIgnoreAttribute>();
if (ignoreAttribute != null) continue;
var columnName = prop.Name.ToLower();
var cqlType = GetCassandraType(prop.PropertyType);
cql.Append($"{columnName} {cqlType}, ");
}
cql.Length -= 2; // Remove last comma and space
cql.Append($", PRIMARY KEY ({primaryKey.Name.ToLower()}))");
session.Execute(cql.ToString());
}
private static string GetCassandraType(Type type)
{
// 基础类型处理
switch (Type.GetTypeCode(type))
{
case TypeCode.String: return "text";
case TypeCode.Int32: return "int";
case TypeCode.Int64: return "bigint";
case TypeCode.Boolean: return "boolean";
case TypeCode.DateTime: return "timestamp";
case TypeCode.Byte: return "tinyint";
}
if (type == typeof(Guid)) return "uuid";
if (type == typeof(DateTimeOffset)) return "timestamp";
if (type == typeof(Byte[])) return "blob";
// 处理集合类型
if (type.IsGenericType)
{
var genericType = type.GetGenericTypeDefinition();
var elementType = type.GetGenericArguments()[0];
if (genericType == typeof(List<>))
return $"list<{GetCassandraType(elementType)}>";
if (genericType == typeof(HashSet<>))
return $"set<{GetCassandraType(elementType)}>";
if (genericType == typeof(Dictionary<,>))
{
var keyType = type.GetGenericArguments()[0];
var valueType = type.GetGenericArguments()[1];
return $"map<{GetCassandraType(keyType)}, {GetCassandraType(valueType)}>";
}
}
throw new NotSupportedException($"不支持的类型: {type.Name}");
}
}
}