web-dev-qa-db-fra.com

Génération et accès aux procédures stockées à l'aide du noyau Entity Framework

J'implémente l'API Web de base Asp.Net, le noyau de l'entité, l'approche de la base de données à l'aide de Visual Studio 2017. J'ai réussi à générer les fichiers de contexte et de classe basés sur une base de données existante. J'ai besoin d'accéder à des procédures stockées en utilisant mon contexte. Dans les versions précédentes du framework entity, il était simple de sélectionner les objets de procédure stockée dans l'assistant et de générer un edmx contenant ces objets. Je pouvais ensuite accéder aux procédures stockées via les objets de type complexe exposés par le cadre de l'entité. Comment puis-je faire la même chose dans le noyau du cadre d'entité? Un exemple aiderait?

8
Tom

La première approche de base de données n’existe pas dans EF Core avec les fichiers edmx. Au lieu de cela, vous devez utiliser Scaffold-DbContext. 

Installer les packages Nuget Microsoft.EntityFrameworkCore.Tools et Microsoft.EntityFrameworkCore.SqlServer.Design

Scaffold-DbContext "Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

mais cela n'obtiendra pas vos procédures stockées. Il est toujours en chantier, problème de suivi # 245

Mais, pour exécuter les procédures stockées, utilisez FromSql qui exécute les requêtes SQL RAW

par exemple.

var products= context.Products
    .FromSql("EXECUTE dbo.GetProducts")
    .ToList();

A utiliser avec des paramètres

var productCategory= "Electronics";

var product = context.Products
    .FromSql("EXECUTE dbo.GetProductByCategory {0}", productCategory)
    .ToList();

ou 

var productCategory= new SqlParameter("productCategory", "Electronics");

var product = context.Product
    .FromSql("EXECUTE dbo.GetProductByName  @productCategory", productCategory)
    .ToList();

Il existe certaines limitations pour l’exécution de requêtes SQL RAW ou de procédures stockées. Vous ne pouvez pas l’utiliser pour INSERT/UPDATE/DELETE. si vous voulez exécuter des requêtes INSERT, UPDATE, DELETE, utilisez la commande ExecuteSqlCommand

var categoryName = "Electronics";
dataContext.Database
           .ExecuteSqlCommand("dbo.InsertCategory @p0", categoryName);
12
Rohith

Les exemples ci-dessus fonctionnent correctement lors de l'exécution d'une procédure stockée si vous vous attendez à ce que l'ensemble de résultats soit identique à tout objet déjà défini. Mais que faire si vous voulez un résultat qui n'est pas supporté? Selon les développeurs d'EF Core 2, c'est une fonctionnalité qui va venir, mais il existe déjà aujourd'hui une solution facile.

Créez le modèle que vous souhaitez utiliser pour votre sortie. Ce modèle représentera la sortie, pas une table dans la base de données.

namespace Example.EF.Model
{
    public class Sample
    {
        public int SampleID { get; set; }
        public string SampleName { get; set; }
    }
}

Ajoutez ensuite à votre contexte un nouveau DBSet avec votre modèle:

public virtual DbSet<Sample> Sample { get; set; }

Et ensuite, faites comme ci-dessus et utilisez votre modèle pour la sortie:

var products = _samplecontext.Sample
      .FromSql($"EXEC ReturnAllSamples {id}, {startdate}, {enddate}").ToList();

J'espère que cela aide quelqu'un.

8
Sami

La solution de contournement que nous utilisons dans EF Core pour exécuter les procédures stockées afin d'obtenir les données consiste à utiliser la méthode FromSql. Vous pouvez exécuter la procédure stockée de la manière suivante:

List<Employee> employees = dbcontext.Employee
                    .FromSql("GetAllEmployees").ToList();

Mais pour Create, Update et Delete, nous utilisons ExecuteSqlCommand comme celui ci-dessous:

var employee = "Harold Javier";
dbcontext.Employee
           .ExecuteSqlCommand("InsertEmployee @emp", employee);
2
Harold Javier

La solution Rohith/Harold Javier/Sami a fourni des travaux. J'aimerais ajouter que vous pouvez créer un projet EF6 distinct pour générer les classes C # des résultats, puis copier les fichiers dans votre projet EFCore. Si vous modifiez un proc stocké, vous pouvez mettre à jour le fichier de résultat en utilisant les méthodes décrites ici: Procédures stockées et mise à jour d'EDMX

Si vous avez besoin d'interfaces TypeScript correspondantes, vous pouvez installer ce générateur de définition TypeScript d'extension VS2017: https://marketplace.visualstudio.com/items?itemName=MadsKristensen.TypeScriptDefinitionGenerator

Il reste quelques copies à effectuer, mais cela est moins fastidieux que de créer les classes manuellement.

Edit: il existe une extension VS2017 pour la génération de dbconext https://marketplace.visualstudio.com/items?itemName=ErikEJ.EFCorePowerTools . Il ne fait pas de procédures stockées, mais il fournit un élément de menu clic droit à partir d'un projet VS au lieu de la ligne de commande Scaffold-DbContext.

0
Seanli