如何在.NET实体框架中获取Oracle的下一个序列值?

xyhw6mcr  于 2022-11-19  发布在  .NET
关注(0)|答案(4)|浏览(180)

我有一个web api post方法,它会在我的Oracle数据库的表中插入一个新行。我在表的主键(序列值)方面遇到了问题。如何在实体框架中执行my_primary_key_seq.nextval?目前,此代码可以工作,但当通过旧的.net web表单(使用序列下一个值作为下一个主键)插入新行时,它将违反PK唯一约束。

decimal nextPK = context.FORMPPs.OrderByDescending(p => p.PPID).FirstOrDefault().PPID + 1;
item.PPID = nextPK;
context.FORMPPs.Add(item);
int result = context.SaveChanges();
k5ifujac

k5ifujac1#

我也遇到了同样的问题,在这个网站和Oracle的帮助下解决了这个问题。我假设你使用的是Database First,因为你提到了另一个遗留应用程序使用的是同一个数据库。
有几件事我必须做。就像丹尼尔Gabriel提到的,如果你让Oracle来管理身份,你就不需要调用序列来找到号码,数据库会帮你处理。但是要让它工作起来有点棘手,因为你可能需要对数据库做一系列的修改。
1.在标识列上创建序列(您已经这样做了)。
1.创建触发器以在插入时自动调用序列. http://www.oracle-base.com/articles/misc/autonumber-and-identity.php
1.修改您的实体框架模型。我使用EF数据库第一,并发现这篇文章解释我需要修改模型,以设置表的标识列的属性为
StoreGeneratedPattern="Identity"
Oracle entity in VS entity framework doesnt update the primary key in code
1.但我不喜欢每次从数据库刷新EF模型时都必须重新添加此更改。双击.edmx文件,然后在数据库图表中找到您的表,突出显示图表中的标识列,并在属性窗口中将StoreGeneratedPattern值更改为Identity。这样,即使您更新EF模型,它也会保持不变。

46scxncf

46scxncf2#

我解决这个问题的方法是使用原始SQL查询从序列中选择一个新值。
也就是说

decimal nextPK = context.Database.SqlQuery<decimal>("SELECT my_primary_key_seq.nextval FROM dual").First();

然后在将新对象添加到上下文中之前将该值赋给新对象。

0vvn1miw

0vvn1miw3#

我用这个作为参考:
https://github.com/dotnet/EntityFramework.Docs/tree/main/samples/core/Querying/RawSQL

数据/Oracle序列上下文.cs

using Microsoft.EntityFrameworkCore;

 
namespace EFQuerying.RawSQL;

public class OracleSequenceContext : DbContext
{
    public DbSet<OracleSequence> dbsetOracleSequences { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder
        .Entity<OracleSequence>(
            eb =>
            {
                eb.HasNoKey();                
            });
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        // don't put this in code.
        optionsBuilder.UseOracle("Data Source=XXXXXXX;User ID=TTTTT;Password=PPPPP;");
    }
}

Oracle序列.cs

using System.Collections.Generic;

namespace EFQuerying.RawSQL;
 
public class OracleSequence
{
    public int SequenceValue { get; set; }
    

}

用法:

using (var seqContext = new OracleSequenceContext())
    {
        var seqList = seqContext.dbsetOracleSequences
            .FromSqlRaw("SELECT SEQ_PUBLICATION.NEXTVAL as SequenceValue FROM DUAL")
            .ToList();

        Publication.PublicationId = seqList[0].SequenceValue;
   }
7gs2gvoe

7gs2gvoe4#

我的两分贡献:

string querySeq = "SELECT SCH.YOUR_SEQUENCE.NEXTVAL FROM DUAL";
var conn = (OracleConnection)dbContext.Database.GetDbConnection();
conn.Open();
var command = new OracleCommand(querySeq, conn);
decimal sequence = (decimal) command.ExecuteScalar();

您可以从上下文获取数据库连接,并将其与OracleCommand类一起使用,以便直接使用www.example.com库执行SQL查询ODP.net。

相关问题