我有一个从 Postgres 中的序列返回值的方法:
public long GetSId(DatabaseFacade d, string sequenceName)
{
var result = new NpgsqlParameter(":result", NpgsqlDbType.Integer)
{
Direction = System.Data.ParameterDirection.InputOutput,
Value = 0
};
d.ExecuteSqlRaw($"SELECT nextval('{sequenceName}')", result);
return (long)result.Value;
}
我有一个形成数据的方法:
private List<CrossingsResult> FormCrossingResult()
{
var d = _dbContext.Database;
var crosswalks = _dbContext.Crosswalks
.Select(x => new CrossingsResult
{
SId = GetSId(d, _sequenceName),
...
}).ToList();
return crosswalks;
问题是当我调用 Select 内部的方法时,SId 不会改变(例如,它将为所有记录设置相同的 SId 值)。但如果我在人行横道外调用该方法,它就会起作用 就像这里:
private List<CrossingsResult> FormCrossingResult()
{
var d = _dbContext.Database;
Console.WriteLine($"First call: {GetSId(d, _sequenceName)}");
Console.WriteLine($"Second call: {GetSId(d, _sequenceName)}");
Console.WriteLine($"Third call: {GetSId(d, _sequenceName)}");
var crosswalks = _dbContext.Crosswalks
.Select(x => new CrossingsResult
{
SId = GetSId(d, _sequenceName),
...
}).ToList();
foreach (var crosswalk in crosswalks)
{
Console.WriteLine(crosswalk.SId);
}
return crosswalks;
结果是这样的:
我尝试用 for 循环来实现它并且它有效:
private List<CrossingsResult> FormCrossingResult()
{
var d = _dbContext.Database;
var crosswalks = _dbContext.Crosswalks
.Select(x => new CrossingsResult
{
...
}).ToList();
foreach (var crosswalk in crosswalks)
{
crosswalk.SId = GetSId(d, _sequenceName);
}
return crosswalks;
但我想要在 Select 内部调用该方法并使其不使用 for 循环
您使用
nextval
的方式是错误的......
从技术上讲,传递给 nextval
() 函数的参数实际上是来自 pg_class
系统目录视图的 OID。当您传递序列的名称时,Postgres 会查找其 OID 并使用它。 (在您的情况下,从该点开始它将返回 123,直到创建新行)。
向表中插入数据时可以使用
nextval
() 函数。这允许您拥有一个包含所有行的连续值的列。