下一个是我的问题。
我的代码中有下一个简单模型:
public class Client
{
public Guid Id { get; set; }
public string Name { get; set; }
}
我为其定义了一个映射:
public class CustomMappings : Mappings
{
public CustomMappings()
{
For<Client>().TableName("clients")
.PartitionKey(x => x.Id);
}
}
我通过Table<TEntity>.CreateIfNotExist()
方法创建了表格:
var table = new Table<Client>(session);
table.CreateIfNotExists();
然后我可以通过以下方式插入数据:
IMapper mapper = new Mapper(session);
var client = new Client
{
Id = Guid.NewGuid(),
Name = "John Smith"
};
await mapper.UpdateAsync(client);
此后,我通过添加新属性更改了模型:
public class Client
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
}
我需要更改此表,因为我想向其添加姓氏列。 当然,当我尝试插入值时,我会遇到一个例外:
Cassandra.InvalidQueryException: Undefined column name surname
at Cassandra.Requests.PrepareHandler.Prepare(PrepareRequest request, IInternalSession session, Dictionary`2 triedHosts)
at Cassandra.Requests.PrepareHandler.Prepare(IInternalSession session, Serializer serializer, PrepareRequest request)
at Cassandra.Session.PrepareAsync(String query, IDictionary`2 customPayload)
at Cassandra.Mapping.Statements.StatementFactory.GetStatementAsync(ISession session, Cql cql, Nullable`1 forceNoPrepare)
at Cassandra.Mapping.Mapper.ExecuteAsync(Cql cql)
但是类Cassandra.Data.Linq.Table<TEntity>
既不包含.AlterOrCreate()
也不包含.Alter()
方法。另外,.GetAlter()
中没有Cassandra.Mapping.Statements.CqlGenerator
方法。
哪种方法更适合解决此问题?我有两个假设(除了使用必要的方法创建请求请求到github上的datastax csharp驱动程序存储库:)。
我是Cassandra的新手,我怀疑图书馆中没有必要的方法是有充分理由的。也许,由于Cassandra是分布式数据库,更改后是否存在一致性问题?
答案 0 :(得分:2)
应该非常准确地完成Cassandra模式的更改-您对它的分布式性质是正确的,并且在进行更改时需要考虑到。通常,建议仅通过一个节点进行更改,并且在执行任何DDL语句(创建/删除/更改)后,您需要检查架构协议(例如,通过Metadata
类的method CheckSchemaAgreementAsync
) ,并且在架构达成一致之前不要执行下一条语句。
自己讨论更改-我不确定C#驱动程序是否能够自动生成架构更改,但是您可以按照C documentation中的说明将更改作为CQL命令执行(请仔细阅读有关限制的信息!)。模式更改可以分为2组:
在第一组中,我们可以执行以下操作(也许不是完整列表):
第二组包括其他所有内容:
数据迁移可以通过不同的工具完成,并且可能取决于特定的要求,例如类型更改等。但这是不同的事情。