Как выполнить (вызвать) хранимую процедуру из ASP.NET Web API? - PullRequest
0 голосов
/ 07 сентября 2018

Сегодня я узнал, как разрабатывать веб-API-сервисы в ASP.NET с использованием Entity Data Model и кода в первую очередь.До сих пор я создал веб-сервис и получил формат Json.Но сейчас я не знаю, как извлечь данные из выполнения хранимой процедуры.Чтобы проиллюстрировать мой вопрос, я разработал тестовое упражнение.Любая помощь приветствуется.

Сначала я создал таблицу в своей базе данных и заполнил ее случайной информацией:

 CREATE TABLE dbo.web_api_Test
 (
     Id INT,
     Name VARCHAR(255),
     Age REAL,
     Country VARCHAR(255),
     Savings REAL

     PRIMARY KEY(Id)
 );

 INSERT INTO dbo.web_api_Test(Id, Name, Age, Country, Savings)
 VALUES  (1, 'Luis', 30,'USA',45.90),
         (2, 'Keny', 19,'Netherlands',105.50),
         (3, 'Sam', 23,'Germany',5.50),
         (4, 'Deysi', 40,'Canada',22.10),
         (5, 'Eliana', 67,'Mexico',1067.50),
         (6, 'Bear', 22,'France',95.00),
         (7, 'Susan', 32,'Chile',125.70),
         (8, 'Zac', 21,'Italy',34.50),
         (9, 'Saito', 53,'Japan',10.25);

Затем я создал хранимую процедуру:

 CREATE PROCEDURE FindPeople 
      (@Country NVARCHAR(10)) 
 AS 
     SELECT *
     FROM dbo.web_api_Test 
     WHERE Country = @Country
 GO

Использование Visual Studio2017 Я создал всю структуру для вызова веб-API.

Мой класс модели сущностей:

public partial class Modelo : DbContext
{
    public Modelo() : base("name=Modelo") 
    {
    }

    public DbSet<web_api_Test> web_api_Test { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<web_api_Test>()
            .Property(e => e.Name)
            .IsUnicode(false);

        modelBuilder.Entity<web_api_Test>()
            .Property(e => e.Country)
            .IsUnicode(false);
    }
}

Мой класс модели таблиц

public partial class web_api_Test
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }

    [StringLength(255)]
    public string Name { get; set; }

    public float? Age { get; set; }

    [StringLength(255)]
    public string Country { get; set; }

    public float? Savings { get; set; }
 }

Мой класс контроллеров

public class web_api_TestController : ApiController
{
    private Modelo db = new Modelo();

    // GET: api/web_api_Test
    public IQueryable<web_api_Test> Getweb_api_Test()
    {
        return db.web_api_Test;
    }

    // GET: api/web_api_Test/5
    [ResponseType(typeof(web_api_Test))]
    public async Task<IHttpActionResult> Getweb_api_Test(int id)
    {
        web_api_Test web_api_Test = await db.web_api_Test.FindAsync(id);

        if (web_api_Test == null)
        {
            return NotFound();
        }

        return Ok(web_api_Test);
    }

    // PUT: api/web_api_Test/5
    [ResponseType(typeof(void))]
    public async Task<IHttpActionResult> Putweb_api_Test(int id, web_api_Test web_api_Test)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        if (id != web_api_Test.Id)
        {
            return BadRequest();
        }

        db.Entry(web_api_Test).State = EntityState.Modified;

        try
        {
            await db.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!web_api_TestExists(id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return StatusCode(HttpStatusCode.NoContent);
    }

    // POST: api/web_api_Test
    [ResponseType(typeof(web_api_Test))]
    public async Task<IHttpActionResult> Postweb_api_Test(web_api_Test web_api_Test)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        db.web_api_Test.Add(web_api_Test);

        try
        {
            await db.SaveChangesAsync();
        }
        catch (DbUpdateException)
        {
            if (web_api_TestExists(web_api_Test.Id))
            {
                return Conflict();
            }
            else
            {
                throw;
            }
        }

        return CreatedAtRoute("DefaultApi", new { id = web_api_Test.Id }, 
   web_api_Test);
    }

    // DELETE: api/web_api_Test/5
    [ResponseType(typeof(web_api_Test))]
    public async Task<IHttpActionResult> Deleteweb_api_Test(int id)
    {
        web_api_Test web_api_Test = await db.web_api_Test.FindAsync(id);

        if (web_api_Test == null)
        {
            return NotFound();
        }

        db.web_api_Test.Remove(web_api_Test);
        await db.SaveChangesAsync();

        return Ok(web_api_Test);
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }

        base.Dispose(disposing);
    }

    private bool web_api_TestExists(int id)
    {
        return db.web_api_Test.Count(e => e.Id == id) > 0;
    }
}

Эти снимки экрана являются результатами, которые я получаю при использовании IIS Google

enter image description here

enter image description here

Как изменить код для вызова хранимой процедуры FindPeople?

Спасибо

Редактировать: я попробовал следующий код:

    [HttpGet, Route("api/TestStoreProcN")]
    public IQueryable<web_api_Test> GetStore(String country)
    {
        var getDataLogs = db.web_api_Test.SqlQuery<web_api_Test>("exec 
   FindPeople @Country", country).AsQueryable();
        return getDataLogs;
    }

Но я получил следующую ошибку:

enter image description here

На основе ответа Пранава Сингха я реализовал следующий метод, и он работает.

Ответ 1:

    [HttpGet, Route("api/TestProcedure/{country}")]
    public List<web_api_Test> GetList(string country)
    {

        SqlConnection connection = new SqlConnection();

        connection.ConnectionString =
        "Data Source=myserver;" +
        "Initial Catalog=mydatabase;" +
        "User id=myuser;" +
        "Password=secret;";

        connection.Open();

        string procedureName = "[dbo].[FindPeople]";
        var result = new List<web_api_Test>();
        using (SqlCommand command = new SqlCommand(procedureName, 
        connection))
        {
            command.CommandType = CommandType.StoredProcedure;
            command.Parameters.Add(new SqlParameter("@Country", country));

            using (SqlDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    int id = int.Parse(reader[0].ToString());
                    string name = reader[1].ToString();
                    float? age = float.Parse(reader[2]?.ToString());
                    string Country = reader[3].ToString();
                    float? savings = float.Parse(reader[4]?.ToString());
                    web_api_Test tmpRecord = new web_api_Test()
                    {
                        Id = id,
                        Name = name,
                        Age = age,
                        Country = country,
                        Savings = savings
                    };
                    result.Add(tmpRecord);
                }
            }
        }
        return result;
    } 

Но теперь я хотел бы знать, как получить те же результаты, используя Entity Framework.Как я мог это сделать?Любая ссылка или предложение приветствуется.

Ответ 2:

В конце я нашел решение, используя EF:

    [HttpGet, Route("api/TestProcedure/{country}")]
    public List<web_api_Test> GetListProcedure(string country)
    {
        var parameter = new SqlParameter {
            ParameterName ="Country",
            Value =country};

        var result= db.web_api_Test.SqlQuery("EXEC FindPeople 
       @Country",parameter).ToList();

        return result;
    }

Спасибо за вашу помощь.

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

Вы можете использовать базовую базу данных в своем контексте напрямую, используя context.SqlQuery, в том числе вызов хранимых процедур. Например, что-то похожее на это должно работать;

var parameter = new SqlParameter {
                     ParameterName = "Country",
                     Value = "USA"
            };

var countries= context.web_api_Test.SqlQuery<web_api_Test>("exec FindPeople @Country", parameter).ToList<web_api_Test>();

Дополнительные сведения см. В справочнике MSDN. Необработанные SQL-запросы

0 голосов
/ 07 сентября 2018

Я не использовал EF в течение длительного времени по многим причинам. Если вы в порядке с прямым подходом, вы можете попробовать это:

public List<web_api_Test> GetList(string country){
    string procedureName = "[dbo].[FindPeople]";
    var result = new List<web_api_Test>();
    using (SqlCommand command = new SqlCommand(procedureName, connection))
    {
        command.CommandType = CommandType.StoredProcedure;
        command.Parameters.Add(new SqlParameter("@Country", country));

        using (SqlDataReader reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                int id = int.Parse(reader[0].ToString());
                string name  = reader[1].ToString();
                float? age = float.Parse(reader[2]?.ToString()); 
                string Country   = reader[3].ToString();
                float? savings = float.Parse(reader[4]?.ToString()); 
                web_api_Test tmpRecord = new web_api_Test()
                {
                    Id = id,
                    Name =Name ,
                    Age =age,
                    Savings =savings
                };
                result.Add(tmpRecord);
            }
        }
    }
    return result;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...