我正在编写一个新的ASP.NET Core Web API,我的需求之一是能够利用EF Core 3.1获取SQL Server中定义的sequence的下一个值,作为我需要存储的记录的ID。
我一直在努力寻找一种方法来实现这一点--在EF 6.x中,我直接在DbContext
后代上使用了一种方法,如下所示:
public int GetNextSequenceValue()
{
var rawQuery = Database.SqlQuery<int>("SELECT NEXT VALUE FOR dbo.TestSequence;");
var task = rawQuery.SingleAsync();
int nextVal = task.Result;
return nextVal;
}
对于EF Core 2.1以上的版本,我本来可以使用Database.ExecuteSqlCommand()
来运行SQL代码段并返回结果。但在EF Core 3.x中,我似乎运气不佳......
我知道在DbSet
上有.FromSqlRaw()
和.FromSqlInterpolated
方法-但由于我只需要返回序列的下一个值(一个INT
),这是行不通的。我还知道这些方法也存在于context.Database
级别,看起来它非常接近我在EF 6.x中的方法-但在这里,这些方法只返回受影响的行数-我还没有找到从SEQUENCE
发回新值的方法。
在EF Core 3.x中,我真的必须求助于古老的ADO .NET代码来获取那个值吗?真的没有办法执行任意的SQL片段并从上下文中获取一些结果吗?
6条答案
按热度按时间798qvoo81#
如果要运行任意TSQL批处理并返回标量值,可以按如下方式执行:
lstz6jyr2#
看起来执行原始SQL不是EF Core的优先事项,所以到目前为止(EF Core 3.1),它只公开提供了几个基本的有限方法。
FromSql
需要实体类型或keyless entity type,ExecuteSqlRaw
/ExecuteSqlInterpolated
是到ADO .NETExecuteNonQuery
的“现代”桥梁,后者返回受影响的行。好的方面是EF Core构建在公共服务架构之上,因此它可以用来添加一些缺失的功能。例如,服务可以用来构建所谓的IRelationalCommand,它具有所有
DbCommand
执行方法,特别是SQL所需的ExecuteScalar
。由于EF Core模型支持序列,因此还有一项服务用于构建检索下一个值所需的
IRelationalCommand
(由HiLo值生成器内部使用)。话虽如此,下面是使用上述概念的定制方法的示例实现:
pbpqsu0x3#
在您的Fluent API配置中,您可以创建将ID自动设置为Sequence中的下一个值的迁移
用于创建序列:
从此处阅读更多信息:https://www.talkingdotnet.com/use-sql-server-sequence-in-entity-framework-core-primary-key/
2nc8po8w4#
对于甲骨文版本的这个问题的痛苦的人,这里有一个解决方案:
nkcskrwz5#
很丑,但我能想到的最好的东西:
1tuwyuhd6#
此代码应适用于各种情况: