web-dev-qa-db-fra.com

Comment obtenir la valeur suivante de la séquence SQL Server dans Entity Framework?

Je souhaite utiliser SQL Server sequence objects dans Entity Framework pour afficher la séquence numérique avant de l'enregistrer dans la base de données. 

Dans le scénario actuel, je fais quelque chose de connexe par incrément de un dans la procédure stockée (valeur précédente stockée dans une table) et en passant cette valeur au code C # 

Pour cela, il me fallait une table, mais je souhaite maintenant la convertir en un objet sequence (cela donnera-t-il un avantage?). 

Je sais comment créer une séquence et obtenir la valeur suivante dans SQL Server. 

Mais je veux savoir comment obtenir la valeur suivante de l'objet sequence de SQL Server dans Entity Framework? 

Je suis incapable de trouver des réponses utiles dans Questions connexes dans SO. 

Merci d'avance.

24
ManirajSS

Vous pouvez créer une procédure stockée simple dans SQL Server qui sélectionne la valeur de séquence suivante comme suit:

CREATE PROCEDURE dbo.GetNextSequenceValue 
AS 
BEGIN
    SELECT NEXT VALUE FOR dbo.TestSequence;
END

vous pouvez ensuite importer cette procédure stockée dans votre modèle EDMX dans Entity Framework, appeler cette procédure stockée et extraire la valeur de séquence de la manière suivante:

// 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);
}

Update: en fait, vous pouvez ignorer la procédure stockée et simplement exécuter cette requête SQL brute à partir de votre contexte EF:

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;
    }
}
37
marc_s

Comme j'utilise Code First et que je ne souhaite pas utiliser de DDL supplémentaire, voici ce que je fais: (EF Core 2.1, SQL Server)

Définir la séquence:

protected override void OnModelCreating( ModelBuilder modelBuilder )
{
    modelBuilder.HasSequence("MySequence");
}

Et pour le récupérer, j'ajoute la fonction suivante au contexte:

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;
}
10
SeSpoon

Si vous souhaitez le faire en dehors d'une procédure stockée, vous pouvez créer une classe d'entité contenant uniquement une chaîne ou un entier (quelle que soit votre séquence renvoyée), puis exécuter du code SQL brut. Ensuite, utilisez simplement votre objet ou votre chaîne comme vous le souhaitez.

 SEQ_TXN_ID txn_id= _context.SEQ_TXN_IDs.SqlQuery("SELECT txn_id_seq.NEXTVAL txn_ID FROM DUAL").FirstOrDefault();
0
user2460920