我尝试向我的 Marten DB 添加新的“自定义”序列,以获取新用户的用户 ID(在注册期间)。
builder.Services.AddMarten(o =>
{
o.Connection(builder.Configuration.GetConnectionString("MartenPg"));
if (builder.Environment.IsDevelopment())
o.AutoCreateSchemaObjects = AutoCreate.All;
o.Storage.ExtendedSchemaObjects.Add(new Sequence("userId_seq"));
}).ApplyAllDatabaseChangesOnStartup().UseLightweightSessions();
后来我能够访问下一个序列值:
var userId = session.Query<Int64>("select nextval('userId_seq')").First();
问题出在上面的代码中:第一次运行它有效:将
userId_seq
添加到数据库中。但在第二次启动时,它尝试再次添加 - 但序列已经存在,因此失败。试图找到一种方法来确定序列是否已添加 - 但找不到任何 - ExtendedSchemaObjects
始终为空。否则 - 我认为这不是我的错,因为方法名称ApplyAllDatabaseChangesOnStartup
建议我它应该由内置迁移工具确定。
有什么建议如何解决这个问题吗?
谢谢!
使用小写序列名称(在 PG 中始终只使用小写名称,让你的生活变得轻松)
一些背景知识:如果您不在 PG 中双引号标识符,它会自动转换为小写。同样,当查询序列(或任何其他对象)时,除非用双引号引起来,否则它会转换为小写形式。
CREATE SEQUENCE TEST;
SELECT NEXTVAL('test'); --OK
SELECT NEXTVAL('teST'); --OK
SELECT NEXTVAL('"test"'); --OK, lower-case name is found
SELECT NEXTVAL('"TEST"'); --ERROR, nothing found.
CREATE SEQUENCE "TEST2";
SELECT NEXTVAL('test2'); --ERROR, nothing found.
SELECT NEXTVAL('"TEST2"'); --OK, double quoted name with upper case is found
回到貂/黄鼠狼:
创建序列的代码不添加双引号,因此您的标识符将转换为小写。
当您查询
nextval
时,标识符也没有用双引号引起来,因此使用其小写版本并且序列返回所需的值。
下次运行应用程序时,查看序列是否存在的code将按原样使用标识符,因此包含大写字母。该名称下没有序列,因此再次使用已存在的小写名称再次创建序列。