Утверждение результата запроса SQL - PullRequest
1 голос
/ 02 апреля 2019

Я собрал следующий метод:

public static ArrayList DbQueryToArry()
        {
            string SqlCString = "connString";
            SqlConnection connection = null;

            ArrayList valuesList = new ArrayList();

            connection = new SqlConnection(SqlCString);
            connection.Open();

            SqlCommand command = new SqlCommand("Select CLIENTNO, ACCOUNT_Purpose from audit.ACCOUNTS_AUDIT", connection);
            SqlDataReader reader = command.ExecuteReader();

            while (reader.Read())
            {
                valuesList.Add(Convert.ToString(reader[0]));
            }
            return valuesList;
        }

Я хотел бы иметь возможность выполнить такое утверждение:

var a = DbQueryToArry();         
Assert.IsTrue(a.Contains("some value"));

Для данного читателя [0]

valuesList.Add(Convert.ToString(reader[0]));

Я получаю только первый столбец (CLIENTINFO) в массив, а не второй (ACCOUNT_Purpose).Как я должен изменить код, чтобы получить оба?

Кроме того, возвращаемые значения могут быть либо String, либо Int, так что моя текущая версия кода должна обрабатывать оба?

Заранее спасибо.

Ответы [ 6 ]

1 голос
/ 02 апреля 2019

Если мы переключимся с устаревшего ArrayList на что-то вроде IEnumerable<T>:

public static IEnumerable<IDataRecord> DbQueryToArray(string sql) {
  if (null == sql)
    throw new ArgumentNullException(nameof(sql));

  //TODO: do not hardcode connetcion string but read it (say, from Settings)
  string SqlCString = "connString";

  //DONE: Wrap IDisposable into using
  using (SqlConnection connection = new SqlConnection(SqlCString)) {
    connection.Open();

    //DONE: Wrap IDisposable into using
    using (SqlCommand command = new SqlCommand(sql, connection)) {
      //DONE: Wrap IDisposable into using
      using (SqlDataReader reader = command.ExecuteReader()) {
        while (reader.Read()) {
          yield return reader as IDataRecord;
        }
      }
    }
  }
}

тогда вы можете использовать Linq для запроса result:

 var a = DbQueryToArray("Select CLIENTNO, ACCOUNT_Purpose from audit.ACCOUNTS_AUDIT");

 Assert.IsTrue(a.Any(record => 
   Convert.ToString(record["CLIENTNO"]) == "some value")); 

 Assert.IsTrue(a.Any(record => 
   Convert.ToString(record["ACCOUNT_Purpose"]) == "some other value")); 

Если вы не хотите выполнять запрос несколько раз, вы можете материализовать результаты:

 var a = DbQueryToArray("Select CLIENTNO, ACCOUNT_Purpose from audit.ACCOUNTS_AUDIT")
   .ToList();

 Assert.IsTrue(a.Any(record => Convert.ToString(record[0]) == "some value")); 

 Assert.IsTrue(a.Any(record => Convert.ToString(record[1]) == "some other value"));

Наконец (см. Комментарии ниже), если мы хотим проверить, имеет ли любое поле в любой запись значение:

  var a = DbQueryToArray("Select CLIENTNO, ACCOUNT_Purpose from audit.ACCOUNTS_AUDIT")
    .SelectMany(line => {
      // Flatten the cursor into IEnumerable<String>
      string[] result = new string[line.FieldCount];

      for (int i = 0; i < result.Length; ++i)
        result[i] = Convert.ToString(line[i]);

      return result;
    });

  a.Any(item => item == "some value");
0 голосов
/ 02 апреля 2019

Рекомендуется сначала проверить, есть ли в считывателе строки

reader.HasRows

, затем закрыть считыватель и установить соединение

. Ваш код должен выглядеть следующим образом:

public static ArrayList DbQueryToArry()
    {
        string SqlCString = "connString";
        SqlConnection connection = null;

        ArrayList valuesList = new ArrayList();

        connection = new SqlConnection(SqlCString);
        using (connection)
        {
            connection.Open();

            SqlCommand command = new SqlCommand("Select CLIENTNO, ACCOUNT_Purpose from audit.ACCOUNTS_AUDIT", connection);
            SqlDataReader reader = command.ExecuteReader();

            if (reader.HasRows)
            {
                while (reader.Read())
                {
                    valuesList.Add(Convert.ToString(reader[0]));
                    valuesList.Add(Convert.ToString(reader[1])); // add to valuelist
                }
            }

            reader.Close(); // close reader

        } //dispose connection

        return valuesList;
    }
0 голосов
/ 02 апреля 2019

Другие ответы хороши, однако некоторые проблемы

  1. Позволяет прекратить использование ArrayList и использовать List<T> вместо
  2. Позволяет использовать оператор using, где вы можете

Примечание : Я использовал ValueTuple для возврата более 1 поля

* * Пример тысячи двадцать-одина * +1022 *

public static List<(string clientNo, string account)> DbQueryToArray()
{
   const string SqlCString = "connString";

   var valuesList = new List<(string clientNo, string account)>();

   using (var connection = new SqlConnection(SqlCString))
   {
      connection.Open();

      using (var command = new SqlCommand("Select CLIENTNO, ACCOUNT_Purpose from audit.ACCOUNTS_AUDIT", connection))
      {
         var reader = command.ExecuteReader();

         while (reader.Read())
            valuesList.Add(((string)reader[0],(string)reader[1]) );
      }
   }
   return valuesList;
}

Использование

var results = DbQueryToArray();
Assert.IsTrue(results.Any(x => x.clientNo == someValue || x.account == someValue));
0 голосов
/ 02 апреля 2019

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

        while (reader.Read())
        {
            valuesList.Add(Convert.ToString(reader["CLIENTNO"]));
            valuesList.Add(Convert.ToString(reader["ACCOUNT_Purpose"]));
        }

Более того, поскольку вы конвертируете все столбцы в string; Я бы предложил использовать строго типизированную коллекцию, например List<string>, а не ArrayList valuesList = new ArrayList();

0 голосов
/ 02 апреля 2019

Используйте DataTable и SqlDataAdapter, чтобы получить результат запроса в виде таблицы.Примерно так:

string connString = @"your connection string here";
string query = "select * from table";
DataTable dataTable = new DataTable();
SqlConnection conn = new SqlConnection(connString);        
SqlCommand cmd = new SqlCommand(query, conn);
conn.Open();
// create data adapter
SqlDataAdapter da = new SqlDataAdapter(cmd);
// this will query your database and return the result to your datatable
da.Fill(dataTable);
conn.Close();
da.Dispose();

Затем вы можете использовать объект dataTable, чтобы увидеть, существуют ли конкретные значения.

0 голосов
/ 02 апреля 2019

Это потому, что вы читаете только первое значение читателя.Reader.Read() читать каждую строку одну за другой, а Convert.ToString(reader[0])) означает, что вы хотите прочитать первый столбец как строку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...