Как избежать выдачи ошибки, когда SQL Select ничего не возвращает - PullRequest
0 голосов
/ 06 декабря 2008

Я где-то читал, что никогда нельзя использовать условия ошибки в качестве нормального потока программы. Имеет прекрасный смысл для меня ... Но

Приложение C #, расположенное поверх базы данных MySQL. Мне нужно разобрать строковое значение на две части, идентификатор и значение. (Исходные данные поступают из девонской базы данных), затем проверяют значение по справочной таблице. Итак, пара оригинальных строк может выглядеть так:

"6776 Фиолетовый людоед"

"БИК Желтое бикини в горошек (используется в настоящее время)"

"DCP Deuce Coup"

Итак, моя маленькая утилита разбирает каждую строку на идентификатор и описание на основе индекса первого пробела (к счастью, согласованного). Затем я передаю идентификатор для поиска, получаю новое значение и мы отправляемся в путь.

К сожалению, TPTB также решил, что нам больше не нужно вонючее желтое бикини в горошек (используется в настоящее время). Итак, БИК не возвращает строку. Вот фрагмент кода:

    foreach (string product in productTokens) {
      tempProduct = product.Trim();
      if (tempProduct.Length > 0) {
        if (tempProduct.Length < 10) {
          product_id = tempProduct;
        }
        else {
          int charPosition = tempProduct.IndexOf(" ");
          product_id = tempProduct.Substring(0, charPosition);
        }
        try {
          s_product = productAdapter.GetProductName(product_id).ToString();
        }
        catch (Exception e) {
          if (e.Message.ToString() == "Object reference not set to an instance of an object.") {
            s_product = "";
          }
          else {
            errLog.WriteLine("Invalid product ID " + e.Message.ToString());
            Console.WriteLine("Invalid product ID " + e.Message.ToString());
            throw;
          } //else
        } //catch
        if (s_product.Length > 0) {
          sTemp = sTemp + s_product + "; ";
        }
      } //if product.length > 0
    } //foreach product in productTokens

Действительно, действительно ужасно! В частности, часть, где я проверяю на наличие недопустимого идентификатора в блоке catch. Просто должен быть лучший способ справиться с этим.

Если кто-нибудь может мне помочь, я бы очень признателен.

Спасибо.

Ответы [ 3 ]

2 голосов
/ 06 декабря 2008

Вы не должны вызывать ToString () в этот момент, сначала вы должны проверить, является ли возвращенное значение нулевым;

object productName = productAdapter.GetProductName(product_id);
if ( productName != null )
{
    s_product = productName.ToString();
}
else
{
    s_product = String.Empty;
}
1 голос
/ 06 декабря 2008

В дополнение к рекомендациям Роба и Марка и исходя из вашего кода выше, я бы предложил еще одну настройку; Я был бы очень удивлен, если бы productAdapter.GetProductName() не уже вернул String, и в этом случае вызов ToString () для него совершенно избыточен. Если он действительно уже возвращает String, тогда весь ваш блок try / catch становится одной строкой:

s_product = productAdapter.GetProductName(product_id) ?? string.Empty;

Кроме того, я думаю, что было бы полезно упомянуть еще кое-что, что уже возвращает String - Exception.Message. Поэтому все различные места, где вы вызываете ToString () в вашем коде, также крайне избыточны.

Кроме того, я бы предложил использовать метод экземпляра String.Split(), а не комбинацию IndexOf и SubString:

product_id = tempProduct.Split(" ", 2)[1];

Наконец, решение о том, какого типа Exception вы поймали, изучив свойство Message, должно быть полностью последним сценарием. Даже если вам действительно нужно , чтобы поймать NullReferenceException здесь, вы должны сделать это явно :

catch (NullReferenceException) {
    s_product = "";
}
catch (Exception e) {
    // Log your invalid ID error condition here
}

P.S .: Я также не совсем уверен, что вообще этот вопрос имеет отношение к MySQL, так как в вашем коде нет никаких свидетельств API БД.

0 голосов
/ 06 декабря 2008

Разве вы не можете просто проверить, возвращает ли GetProductName значение null?

var productName = s_product = productAdapter.GetProductName(product_id);
if(productName == null) { ... do something }
else {
    string name = productName.ToString();
}
...