不允许在cassandracsharpdriver集合中使用非冻结UDT

lf3rwulv  于 2021-06-14  发布在  Cassandra
关注(0)|答案(1)|浏览(376)

我是Cassandra为我的自定义日志 .netcore 项目,我正在使用cassandracsharpdriver。
问题:我已经为日志中的params创建了udt,并将日志表中的paramudt列表添加为冻结。但我得到了一个错误: Non-frozen UDTs are not allowed inside collections . 我不知道为什么会出现这个错误,因为我在日志模型中使用的列表中使用了冻结属性。

logSession.Execute($"CREATE TYPE IF NOT EXISTS {options.Keyspaces.Log}.{nameof(LogParamsCUDT)} (Key text, ValueString text);");

这是模型:

public class Log
    {
        public int LoggingLevel { get; set; }
        public Guid UserId { get; set; }
        public string TimeZone { get; set; }
        public string Text { get; set; }
        [Frozen]
        public IEnumerable<LogParamsCUDT> LogParams { get; set; }
    }

问题是我哪里做错了,是我的udt脚本不正确还是需要在模型中更改。
提前谢谢

kqlmhetl

kqlmhetl1#

我试过用那个模型 Table.CreateIfNotExists 已成功运行。
代码如下:

public class Program
    {
        public static void Main()
        {
            var cluster = Cluster.Builder().AddContactPoint("127.0.0.1").Build();
            var session = cluster.Connect();
            session.CreateKeyspaceIfNotExists("testks");
            session.ChangeKeyspace("testks");
            session.Execute($"CREATE TYPE IF NOT EXISTS testks.{nameof(LogParamsCUDT)} (Key text, ValueString text);");
            session.UserDefinedTypes.Define(UdtMap.For<LogParamsCUDT>($"{nameof(LogParamsCUDT)}", "testks"));
            var table = new Table<Log>(session);
            table.CreateIfNotExists();
            table.Insert(new Log
            {
                LoggingLevel = 1,
                UserId = Guid.NewGuid(),
                TimeZone = "123",
                Text = "123",
                LogParams = new List<LogParamsCUDT>
                {
                    new LogParamsCUDT
                    {
                        Key = "123",
                        ValueString = "321"
                    }
                }
            }).Execute();
            var result = table.First(l => l.Text == "123").Execute();
            Console.WriteLine(JsonConvert.SerializeObject(result));
            Console.ReadLine();
            table.Where(l => l.Text == "123").Delete().Execute();
        }
    }

    public class Log
    {
        public int LoggingLevel { get; set; }
        public Guid UserId { get; set; }
        public string TimeZone { get; set; }
        [Cassandra.Mapping.Attributes.PartitionKey]
        public string Text { get; set; }
        [Frozen]
        public IEnumerable<LogParamsCUDT> LogParams { get; set; }
    }

    public class LogParamsCUDT
    {
        public string Key { get; set; }

        public string ValueString { get; set; }
    }

注意,我必须添加 PartitionKey 否则它不会运行。
以下是它生成的cql语句:

CREATE TABLE Log (
    LoggingLevel int, 
    UserId uuid, 
    TimeZone text, 
    Text text, 
    LogParams frozen<list<"testks"."logparamscudt">>, 
    PRIMARY KEY (Text)
)

如果我移除 Frozen 属性,则会发生以下错误: Cassandra.InvalidQueryException: 'Non-frozen collections are not allowed inside collections: list<testks.logparamscudt>' .
如果你想有这样的专栏 LogParams frozen<list<"testks"."logparamscudt">> 然后 Frozen 属性将起作用。如果您只想冻结udt,即。, LogParams list<frozen<"testks"."logparamscudt">> ,然后 Frozen 属性将不起作用,并且您不能依赖驱动程序来生成 CREATE 给你的声明。
我所有的测试都是针对Cassandra的 3.0.18 使用最新的c#驱动程序( 3.10.1 ).

相关问题