TheBigBearNow Ответов: 2

C# WPF read SQL method


Я создаю метод read/get по Id это мой первый раз, когда я создаю метод с помощью операторов "using", поэтому мне интересно, каким должен быть мой метод. где я должен вернуть продукт, и не пропущу ли я что-нибудь или какие-либо советы/идеи, любой вклад будет оценен по достоинству.

public static Product ReadProductById(int prodId)
        {
            using(SqlConnection connection = ConnectionString.GetSqlConnection())
            {
                string query = "SELET * " +
                               "FROM Products " +
                               "WHERE ProductId = @pid";
                using(SqlCommand cmdRead = new SqlCommand(query, connection))
                {
                    cmdRead.Parameters.AddWithValue("@pid", prodId);
                    using(SqlDataReader reader = cmdRead.ExecuteReader())
                    {
                        if (reader != null)
                        {
                            while (reader.Read())
                            {
                                Product product = new Product()
                                {
                                    ProductId = Convert.ToInt32(reader["ProductId"]),
                                    ProductName = reader["ProductName"].ToString(),
                                    ProductPrice = Convert.ToDecimal(reader["ProductPrice"]),
                                    ProductListedDate = Convert.ToDateTime(reader["ProductListedDate"]),
                                    ProductTax = Convert.ToDecimal(reader["ProductTax"]),
                                    UserId = Convert.ToInt32(reader["UserId"]),
                                    ProductQuantity = Convert.ToInt32(reader["ProductQuantity"]),
                                    ProductTotal = Convert.ToDecimal(reader["ProductTotal"]),
                                    ProductPurchasedDate = Convert.ToDateTime(reader["ProductPurchasedDate"]),
                                    ReceiptId = Convert.ToInt32(reader["ReceiptId"])
                                };
                                return product;
                            }
                        }
                        else { return null; }
                        //return product;
                    }
                }
                    
            }
        }


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

перемещая возврат в разные места, должен ли я иметь продукт, объявленный в верхней части метода? потому что там, куда он сейчас движется, он говорит, что это не в контексте.

TheBigBearNow

публичный статический продукт ReadProductById(int prodId)
{
Продукт продукт = новый продукт();

использование(SqlConnection connection = ConnectionString.GetSqlConnection())
{
строка запроса = "выбрать *" +
"Продукты" +
"Где ProductId = @pid";
используя(sqlcommand, который cmdRead = новый sqlcommand, который(запрос соединения))
{
cmdRead.Параметры.AddWithValue("@pid", prodId);
использование(SqlDataReader reader = cmdRead.Метода executereader())
{
if (reader != null)
{
в то время как (читатель.читать())
{
Продукт product2 = новый продукт()
{
ProductId = Конвертировать.ToInt32(reader["ProductId"]),
ProductName = reader["ProductName"].Метод toString(),
Параметр = Конвертировать.ToDecimal(reader["ProductPrice"]),
ProductListedDate = Конвертировать.ToDateTime(reader["ProductListedDate"]),
ProductTax = Конвертировать.ToDecimal(reader["ProductTax"]),
UserId = Конвертировать.ToInt32(reader["UserId"]),
ProductQuantity = Конвертировать.ToInt32(reader["ProductQuantity"]),
ProductTotal = Конвертировать.ToDecimal(reader["ProductTotal"]),
ProductPurchasedDate = Конвертировать.ToDateTime(reader["ProductPurchasedDate"]),
ReceiptId = Конвертировать.ToInt32(reader["ReceiptId"])
};
продукт = product2;
}
}
else { product = null; }
}
}
}
возвращенное изделие;
}


это то, что я собираюсь попробовать.

PRAKASH9

Да, вы должны сделать декларацию глобально.

CHill60

Нет, не глобально. См. мое решение для получения справки о Области применения

2 Ответов

Рейтинг:
2

#realJSOP

Я делаю это таким образом:

SqlConnection conn = null;
SqlCommand cmd = null;
try
{
    using (conn = new SqlConnection("blah blah"))
    {
        conn.Open();
        using (cmd = new SqlCommand(...))
        {
            //... your code
        }
    }
}
catch (Exception ex)
{
    //... do something appropriate to handle the exception.
}


Объявления conn и cmd переменные перед началом работы using операторы позволяют проверять их свойства в случае возникновения исключения.


CHill60

Разве это не отрицает использование using? MSDN утверждает: "обычно лучше создать экземпляр объекта в операторе using и ограничить его область действия блоком using." (оператор using (Справочник по c#) | Майкрософт документы[^])
Если вы переместите try-catch в блок using, это все равно позволит вам запрашивать любое исключение и по-прежнему извлекать выгоду из утилизации ресурсов.
Однако это все еще не решает реальной проблемы - ОП не понимает области применения

#realJSOP

Нисколько. То using все еще делает очистку для вас - я просто делаю объекты доступными в случае возникновения исключения, чтобы я мог видеть, что в них находится. "Вообще лучше" - это просто руководство, вроде пиратского кодекса.

Рейтинг:
12

CHill60

Ты должен понять scope - прочтите эту статью MSDN Область действия переменных и методов в Microsoft .NET[^]

Глядя на код из вашего комментария, вы объявляете второй Product возражать без всякой на то причины. product там, где он объявлен, это нормально, так как он доступен везде, где вы хотите ссылаться на него. Я думаю, что вы путаетесь между ними. объявление переменная и создание новые случаи его

Обратите внимание, что ваш код не будет работать, потому что вы неправильно написали слово "SELECT" в своем коде. query Есть также ненужные фигурные скобки.

Что-то подобное этому должно быть прекрасно (непроверено!). Пожалуйста, примите к сведению комментарии, которые я добавил.

public static Product ReadProductById(int prodId)
{
   Product product = null;    // Actual instance created in the loop below

   using(SqlConnection connection = ConnectionString.GetSqlConnection())
   {
      string query = "SELECT * FROM Products WHERE ProductId = @pid";

      using(SqlCommand cmdRead = new SqlCommand(query, connection))
      {      
         cmdRead.Parameters.AddWithValue("@pid", prodId);
         using(SqlDataReader reader = cmdRead.ExecuteReader())
         {
            if (reader != null)
            {
               while (reader.Read())   // Do you really need this while here, or just a reader.Read()?
               {
                  product = new Product()   // Could have been done at the declaration
                  ProductId = Convert.ToInt32(reader["ProductId"]),   //Avoid using Convert.ToInt32 - use Int32.TryParse or Int32.Parse instead
                  ProductName = reader["ProductName"].ToString(),
                  ProductPrice = Convert.ToDecimal(reader["ProductPrice"]), //See comment above about Convert.To...
                  ProductListedDate = Convert.ToDateTime(reader["ProductListedDate"]), //See comment above about Convert.To...
                  ProductTax = Convert.ToDecimal(reader["ProductTax"]),
                  UserId = Convert.ToInt32(reader["UserId"]),
                  ProductQuantity = Convert.ToInt32(reader["ProductQuantity"]),
                  ProductTotal = Convert.ToDecimal(reader["ProductTotal"]),
                  ProductPurchasedDate = Convert.ToDateTime(reader["ProductPurchasedDate"]),
                  ReceiptId = Convert.ToInt32(reader["ReceiptId"])
               }
            }
         }
      } 
   }
   return product;
}