Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment puis-je appeler une procédure stockée SQL en utilisant EntityFramework 7 et Asp.Net 5

J'espère avoir bien compris votre problème. Vous avez une PROCÉDURE STORED existante, par exemple dbo.spGetSomeData , dans la base de données, qui renvoie la liste de certains éléments avec certains champs et vous devez fournir les données de la méthode API Web.

La mise en œuvre pourrait porter sur ce qui suit. Vous pouvez définir un vide DbContext comme :

public class MyDbContext : DbContext
{
}

et pour définir appsettings.json avec la chaîne de connexion à la base de données

{
  "Data": {
    "DefaultConnection": {
      "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=MyDb;Trusted_Connection=True;MultipleActiveResultSets=true"
    }
  }
}

Vous devez utiliser Microsoft.Extensions.DependencyInjection pour ajouter MyDbContext au

public class Startup
{
    // property for holding configuration
    public IConfigurationRoot Configuration { get; set; }

    public Startup(IHostingEnvironment env)
    {
        // Set up configuration sources.
        var builder = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
            .AddEnvironmentVariables();
        // save the configuration in Configuration property
        Configuration = builder.Build();
    }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddMvc()
            .AddJsonOptions(options => {
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            });

        services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<MyDbContext>(options => {
                options.UseSqlServer(Configuration["ConnectionString"]);
            });
    }
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        ...
    }
}

Vous pouvez maintenant implémenter votre action WebApi comme suit :

[Route("api/[controller]")]
public class MyController : Controller
{
    public MyDbContext _context { get; set; }

    public MyController([FromServices] MyDbContext context)
    {
        _context = context;
    }

    [HttpGet]
    public async IEnumerable<object> Get()
    {
        var returnObject = new List<dynamic>();

        using (var cmd = _context.Database.GetDbConnection().CreateCommand()) {
            cmd.CommandText = "exec dbo.spGetSomeData";
            cmd.CommandType = CommandType.StoredProcedure;
            // set some parameters of the stored procedure
            cmd.Parameters.Add(new SqlParameter("@someParam",
                SqlDbType.TinyInt) { Value = 1 });

            if (cmd.Connection.State != ConnectionState.Open)
                cmd.Connection.Open();

            var retObject = new List<dynamic>();
            using (var dataReader = await cmd.ExecuteReaderAsync())
            {
                while (await dataReader.ReadAsync())
                {
                    var dataRow = new ExpandoObject() as IDictionary<string, object>;
                    for (var iFiled = 0; iFiled < dataReader.FieldCount; iFiled++) {
                        // one can modify the next line to
                        //   if (dataReader.IsDBNull(iFiled))
                        //       dataRow.Add(dataReader.GetName(iFiled), dataReader[iFiled]);
                        // if one want don't fill the property for NULL
                        // returned from the database
                        dataRow.Add(
                            dataReader.GetName(iFiled),
                            dataReader.IsDBNull(iFiled) ? null : dataReader[iFiled] // use null instead of {}
                        );
                    }

                    retObject.Add((ExpandoObject)dataRow);
                }
            }
            return retObject;
        }
    }
}

Le code ci-dessus s'exécute simplement en utilisant exec dbo.spGetSomeData et utilisez dataRader pour lire tous les résultats et les enregistrer dans dynamic objet. Si vous faisiez $.ajax appel depuis api/My vous obtiendrez les données renvoyées par dbo.spGetSomeData , que vous pouvez directement utiliser dans le code JavaScript. Le code ci-dessus est très transparent. Les noms des champs du jeu de données renvoyés par dbo.spGetSomeData seront les noms des propriétés dans le code JavaScript. Vous n'avez en aucun cas besoin de gérer les classes d'entités dans votre code C#. Votre code C# n'a pas de noms de champs renvoyés par la procédure stockée. Ainsi, si vous souhaitez étendre/modifier le code de dbo.spGetSomeData (renommer certains champs, ajouter de nouveaux champs) vous devrez ajuster uniquement votre code JavaScript, mais pas de code C#.