如何在Entity Framework中获取SQL Server序列的下一个值?

Man*_*jSS 27 c# sql-server orm entity-framework sql-server-2012

我想在Entity Framework中使用SQL Server sequence对象在将数据保存到数据库之前显示数字序列.

在当前场景中,我正在通过在存储过程中增加一个(存储在一个表中的先前值)并将该值传递给C#代码来执行相关操作.

为了实现这一点,我需要一个表,但现在我想将它转换为一个sequence对象(它会给它带来任何好处吗?).

我知道如何在SQL Server中创建序列并获取下一个值.

但我想知道如何sequence在Entity Framework中获取SQL Server的下一个对象值?

我无法在SO 中的相关问题中找到有用的答案.

提前致谢.

mar*_*c_s 40

您可以在SQL Server中创建一个简单的存储过程,选择下一个序列值,如下所示:

CREATE PROCEDURE dbo.GetNextSequenceValue 
AS 
BEGIN
    SELECT NEXT VALUE FOR dbo.TestSequence;
END
Run Code Online (Sandbox Code Playgroud)

然后,您可以将该存储过程导入到Entity Framework中的EDMX模型中,并调用该存储过程并获取序列值,如下所示:

// get your EF context
using (YourEfContext ctx = new YourEfContext())
{
    // call the stored procedure function import   
    var results = ctx.GetNextSequenceValue();

    // from the results, get the first/single value
    int? nextSequenceValue = results.Single();

    // display the value, or use it whichever way you need it
    Console.WriteLine("Next sequence value is: {0}", nextSequenceValue.Value);
}
Run Code Online (Sandbox Code Playgroud)

更新:实际上,您可以跳过存储过程并从EF上下文中运行此原始SQL查询:

public partial class YourEfContext : DbContext 
{
    .... (other EF stuff) ......

    // get your EF context
    public int GetNextSequenceValue()
    {
        var rawQuery = Database.SqlQuery<int>("SELECT NEXT VALUE FOR dbo.TestSequence;");
        var task = rawQuery.SingleAsync();
        int nextVal = task.Result;

        return nextVal;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我怎么用代码优先做到这一点? (5认同)
  • 如果你正在使用**迁移**; 您可以将`CREATE SEQUENCE`脚本添加到迁移中作为`Sql("CREATE SEQUENCE .......");`call (2认同)
  • 你如何处理它的事务? (2认同)

Mar*_*oon 16

由于我使用Code First而且我不想要一些额外的DDL,这是我的方式:(EF Core 2.1,SQL Server)

定义顺序:

protected override void OnModelCreating( ModelBuilder modelBuilder )
{
    modelBuilder.HasSequence("MySequence");
}
Run Code Online (Sandbox Code Playgroud)

为了检索它,我将以下函数添加到上下文中:

public int GetMySequence()
{
   SqlParameter result = new SqlParameter("@result", System.Data.SqlDbType.Int)
   {
      Direction = System.Data.ParameterDirection.Output
   };

   Database.ExecuteSqlCommand(
              "SELECT @result = (NEXT VALUE FOR MySequence)", result);

   return (int)result.Value;
}
Run Code Online (Sandbox Code Playgroud)

  • 你如何在实体中映射它? (2认同)

Wil*_*ill 8

如果其他使用 Entity Framework Core 的人最终看到这里,这对我有用:

var connection = dbContext.Database.GetDbConnection();
connection.Open();
using (var cmd = connection.CreateCommand())
{
    cmd.CommandText = "SELECT NEXT VALUE FOR ACH.FileIDModifier;";
    var obj = cmd.ExecuteScalar();
    int anInt = (int)obj;
}
Run Code Online (Sandbox Code Playgroud)


Nic*_*k B 8

EF 3.1:在 DbContext 中添加以下函数。参考使用 Microsoft.Data.SqlClient;

 public async Task<int> NextValueForSequence(SequenceEnum.Sequence sequence)
    {
        SqlParameter result = new SqlParameter("@result", System.Data.SqlDbType.Int)
        {
            Direction = System.Data.ParameterDirection.Output
        };

        var sequenceIdentifier = sequence.GetType().GetMember(sequence.ToString()).First().GetCustomAttribute<DescriptionAttribute>().Description;

        await Database.ExecuteSqlRawAsync($"SELECT @result = (NEXT VALUE FOR [{sequenceIdentifier}])", result);

        return (int)result.Value;
    }



public class SequenceEnum
{
    public enum Sequence
    {
        [Description("Generate_First_Sequence")]
        FirstSequence,
        [Description("Generate_Second_Sequence")]
        SecondSequence,
    }
}
Run Code Online (Sandbox Code Playgroud)

在调用上下文时

await context.NextValueForSequence(SequenceEnum.Sequence.FirstSequence);
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助 :)