lee loong Ответов: 1

Извлечение данных из базы данных на основе параметра


`ValuesController.cs` (отправка HTTP-запроса, такого как GET, POST, DELETE и т. д):
public class ValuesController : ApiController
    {
        Database_Access_Data.db dblayer = new Database_Access_Data.db();
  
        [HttpPost]
        [Route("api/Values/SendLocation")]
        public IHttpActionResult SendLocation([FromBody]Location cs)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }

                dblayer.SendLocation(cs);

                return Ok("Success");
            }
            catch (Exception e)
            {
                return Ok("Something went Wrong" + e);
            }
        }

        [HttpGet]
        [Route("api/Values/GetLocationHistory")]
        public DataSet GetLocationHistory()
        {
            DataSet ds = dblayer.GetLocationHistory();
            return ds;
        }

        [HttpPost]
        [Route("api/Values/SendDistance")]
        public IHttpActionResult SendDistance([FromBody]Location cs)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }

                dblayer.SendDistance(cs);

                return Ok("Success");
            }
            catch (Exception e)
            {
                return Ok("Something went Wrong" + e);
            }
        }

        [HttpGet]
        [Route("api/Values/GetUser")]
        public DataSet GetUser()
        {
            DataSet ds = dblayer.GetUser();
            return ds;
        }

        [HttpPost]
        [Route("api/Values/FlagingDevice")]
        public IHttpActionResult FlagingDevice([FromBody]Timer cs)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }

                dblayer.FlagingDevice(cs);

                return Ok("Success");
            }
            catch (Exception e)
            {
                return Ok("Something went Wrong" + e);
            }
        }

        [HttpPost]
        [Route("api/Values/SendBox")]
        public IHttpActionResult SendBox([FromBody]Box cs)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }

                dblayer.SendBox(cs);

                return Ok("Success");
            }
            catch (Exception e)
            {
                return Ok("Something went Wrong" + e);
            }
        }
    }
'db.cs` (используется для вызова хранимой процедуры, а также для отправки параметра
public class db
    {
        SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["localhost"].ConnectionString);

        Location cs = new Location();

        public void SendLocation(Location cs)
        {
            SqlCommand com = new SqlCommand("SendGPS",con);
            com.CommandType = CommandType.StoredProcedure;

            com.Parameters.AddWithValue("@DeviceImei", cs.DeviceImei);
            com.Parameters.AddWithValue("@Latitude",cs.Latitude);
            com.Parameters.AddWithValue("@Longitude",cs.Longitude);
            com.Parameters.AddWithValue("@Distance", cs.Distance);
            com.Parameters.AddWithValue("@LocationSend",cs.LocationSend);

            con.Open();
            com.Connection = con;

            com.ExecuteNonQuery();
            con.Close();
        }

        public DataSet GetLocationHistory()
        {
            SqlCommand com = new SqlCommand("GetLocationHistory", con);
            com.CommandType = CommandType.StoredProcedure;

            SqlDataAdapter da = new SqlDataAdapter(com);
            DataSet ds = new DataSet();
            da.Fill(ds);

            return ds;
        }

        public DataSet GetUser()
        {
            SqlCommand com = new SqlCommand("GetUser", con);
            com.CommandType = CommandType.StoredProcedure;

            SqlDataAdapter da = new SqlDataAdapter(com);
            DataSet ds = new DataSet();
            da.Fill(ds);

            return ds;
        }

        public void SendDistance(Location cs)
        {
            SqlCommand com = new SqlCommand("SendDistance", con);
            com.CommandType = CommandType.StoredProcedure;

            com.Parameters.AddWithValue("@DeviceImei", cs.DeviceImei);
            com.Parameters.AddWithValue("@Distance", cs.Distance);
            com.Parameters.AddWithValue("@LocationSend", cs.LocationSend);

            con.Open();
            com.Connection = con;
            com.ExecuteNonQuery();
            con.Close();
        }

        public void FlagingDevice(Timer cs)
        {
            SqlCommand com = new SqlCommand("FlagingDevice", con);
            com.CommandType = CommandType.StoredProcedure;
            com.Parameters.AddWithValue("@Interval", cs.Interval);

            con.Open();
            com.Connection = con;
            com.ExecuteNonQuery();
            con.Close();
        }

        public void SendBox(Box cs)
        {
            SqlCommand com = new SqlCommand("SendBox", con);
            com.CommandType = CommandType.StoredProcedure;

            com.Parameters.AddWithValue("@Id", cs.Id);
            com.Parameters.AddWithValue("@PollingStationID", cs.PollingStationID);
            com.Parameters.AddWithValue("@DeviceImei", cs.DeviceImei);

            con.Open();
            com.Connection = con;
            com.ExecuteNonQuery();
            con.Close();
        }
    }

Хранимая процедура, используемая для возврата данных из таблицы:
SET ANSI_NULLS ON
         GO
         SET QUOTED_IDENTIFIER ON
         GO

         ALTER PROCEDURE [dbo].[FlagingDevice]
             @Interval INT 
         AS 
             DECLARE @Time DATETIME

             IF @Interval = 5
             BEGIN 
                 SET @Time = (SELECT MAX(LocationSend) FROM dbo.Location)

                 SELECT D.imei, L.*, L1.*
                 FROM Device D
                 OUTER APPLY
                     (SELECT  * 
                      FROM dbo.Location L1
                      WHERE L1.DeviceImei = D.Imei 
                      GROUP BY DeviceImei, Latitude, Longitude, Distance, LocationSend
                      HAVING DATEDIFF(MINUTE, LocationSend, @Time) <= @Interval) AS L
                 OUTER APPLY
                     (SELECT TOP 1 L4.ID AS 'Station', L3.Name
                      FROM [dbo].[ElectionDivision] L3, dbo.PollingStation L4
                      WHERE L.Latitude IS NOT NULL 
                        AND L.Longitude IS NOT NULL 
                        AND L.Distance IS NOT NULL 
                        AND L.DeviceImei = D.ImeI) AS L1
              END
              ELSE IF @Interval = 0
              BEGIN 
                  SELECT D.imei, L.*, L1.*
                  FROM Device D
                  OUTER APPLY
                      (SELECT TOP 1 * 
                       FROM dbo.Location L1
                       WHERE L1.DeviceImei = D.Imei 
                       ORDER BY (LocationSend) DESC) AS L
                  OUTER APPLY
                      (SELECT TOP 1 L4.ID AS 'Station', L3.Name
                       FROM [dbo].[ElectionDivision] L3, dbo.PollingStation L4
                       WHERE L.Latitude IS NOT NULL 
                         AND L.Longitude IS NOT NULL 
                         AND L.Distance IS NOT NULL 
                         AND L.DeviceImei = D.ImeI) AS L1
          END
**Update**: я попытался выполнить хранимую процедуру с параметром с помощью SQL-запроса, и она работает, он действительно возвращает строки из таблицы

Что я уже пробовал:

**Update**: я использую sqldatareader и помещаю данные в список, но не знаю, как вернуть метод FlaggingDevice, как показано в классе valuescontroller. Должен ли я создавать список внутри класса или что-то еще? Есть Предложения ?

public List<FlagingDevice> FlagingDevice(FlagingDevice cs)
{

    SqlCommand com = new SqlCommand("FlagingDevice", con);
    com.CommandType = CommandType.StoredProcedure;
    com.Parameters.AddWithValue("@Interval", cs.Interval);
    con.Open();
    com.Connection = con;
    using (SqlDataReader sqlDataReader = com.ExecuteReader())
    {

        int movieGenreIDIndex = sqlDataReader.GetOrdinal("DeviceImei");
        int movieIDIndex = sqlDataReader.GetOrdinal("Latitude");
        int genreIDIndex = sqlDataReader.GetOrdinal("Longitude");
        int genreIDIndex1 = sqlDataReader.GetOrdinal("Distance");
        int genreIDIndex2 = sqlDataReader.GetOrdinal("LocationSend");
        int genreIDIndex3 = sqlDataReader.GetOrdinal("Station");
        int genreIDIndex4 = sqlDataReader.GetOrdinal("Name");
        while (sqlDataReader.Read())
        {
            student.Add(new FlagingDevice()
            {
                DeviceImei = sqlDataReader.IsDBNull(movieGenreIDIndex) ? null : sqlDataReader.GetString(movieGenreIDIndex),
                Latitude = sqlDataReader.IsDBNull(movieIDIndex) ? null : sqlDataReader.GetString(movieIDIndex),
                Longitude = sqlDataReader.IsDBNull(genreIDIndex) ? null : sqlDataReader.GetString(genreIDIndex),
                Distance = sqlDataReader.IsDBNull(genreIDIndex1) ? null : sqlDataReader.GetString(genreIDIndex1),
                LocationSend = sqlDataReader.IsDBNull(genreIDIndex2) ? null : Convert.ToString(sqlDataReader["LocationSend"]),
                Name = sqlDataReader.IsDBNull(genreIDIndex4) ? null : sqlDataReader.GetString(genreIDIndex4)



            });






        }
        sqlDataReader.Close();
        con.Close();
        return student;


    }




}

Atlapure Ambrish

Какую ошибку вы видите?

lee loong

Ошибка которую я вижу заключается в том что он возвращает успех вместо этого я хочу чтобы он возвращал данные из хранимой процедуры

Atlapure Ambrish

Я бы посоветовал вам захватить вызов хранимой процедуры в "SQL profiler" и попытаться запустить его из SQL management studio, чтобы проверить, возвращает ли он предполагаемый результат.

lee loong

Пробовал: хранимая процедура работает по назначению. Единственная проблема заключается в отображении данных через asp.net

Atlapure Ambrish

а как насчет метода api get? видите ли Вы данные в наборе данных, которые вы возвращаете из метода??

С другой стороны, web api всегда должен возвращать данные стандартного формата, например JSON, XML, чтобы они не ограничивались конкретными приложениями. Итак, я бы вернул JSON из методов GetLocationHistory и GetUser.

lee loong

В моей хранимой процедуре у меня есть параметр, который принимает интервал и отображает строки на основе интервала. Я пробовал использовать dataset, но все равно безрезультатно. я попросил некоторых людей в stackoverflow они сказали мне использовать sqldatareader для извлечения данных и я могу получить их но не знаю как отобразить их на контроллере

Atlapure Ambrish

одним из альтернативных вариантов может быть цикл над datareader и скрытие результата в коллекцию некоторого класса, а затем возврат к контроллеру.

F-ES Sitecore

Вы используете ExecuteNonQuery, что означает запуск SQL и игнорирование результатов. Если вы хотите прочитать результаты, вам понадобится что-то вроде ExecuteReader. Вторая проблема заключается в том, что вам, вероятно, придется добавить

УСТАНОВИТЕ NOCOUNT ON

в верхней части SP и операторы типа "SET @Time =" также генерируют 0 результатов строк.

Atlapure Ambrish

Если я не проглядел код, он использует dataset в методе db.cs - GetLocationHistory (), а ExecuteNonQuery используется для других методов сохранения.

F-ES Sitecore

SP, который он опубликовал, он вызывает с помощью ExecuteNonQuery.

1 Ответов

Рейтинг:
9

alexvw

Привет;

Я бы запросил БД и загрузил результаты в DataTable, чтобы позже обработать их для преобразования в список FlagingDevice объекты перед передачей их в пользовательский интерфейс; взгляните на это:

public DataTable FlagingDevice(FlagingDevice cs)
            {
                DataTable dt = new DataTable();

                using (SqlConnection rootConn = con)
                using (SqlCommand sqlCmd = new SqlCommand("FlagingDevice", rootConn))
                {
                    sqlCmd.CommandType = CommandType.StoredProcedure;
                    sqlCmd.Parameters.Add(new SqlParameter("@Interval", cs.Interval));

                    try
                    {
                        rootConn.Open();
dt.Load(sqlCmd.ExecuteReader(CommandBehavior.CloseConnection));
                    }
                    catch (SqlException ex) 
                    { 
                      //Handle errors as you see fit
                    }
                }

                return dt; //output
            }

это создаст, заполнит и вернет DataTable, который затем вы можете повторить, чтобы построить свой список<FlagingDevice>.

Метод преобразования ваших потоков данных в FlagingDevice это не должно представлять для вас никаких проблем.

Надеюсь, это поможет.


lee loong

Я попробовал, и он работает только в том случае, если интервал равен 0, если интервал равен 5, он не вернет строки. Кроме того, параметр продолжает показывать 0, даже если он изменился.

alexvw

Привет Ли,

Поведение, которое вы описываете, связано либо с T-SQL, либо со значением передаваемых параметров. Дважды проверьте их.

Ваше здоровье!

lee loong

Спасибо за вашу помощь, теперь я могу получить данные из хранимой процедуры. Ура!!!!!!!: D