SQL查询结果断言

时间:2019-04-02 06:39:09

标签: c# sql

我整理了以下方法:

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 个答案:

答案 0 :(得分:1)

如果我们从陈旧 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"));

最后(请参阅下面的注释),如果我们要测试 any 记录中的 any 字段是否具有值:

  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");

答案 1 :(得分:0)

这是因为您仅读取读取器的第一个值。 Reader.Read()逐行读取每一行,Convert.ToString(reader[0]))表示您想将第一列读取为字符串。

答案 2 :(得分:0)

使用DataTableSqlDataAdapter以表的形式获取查询结果。像这样:

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对象查看是否存在特定值。

答案 3 :(得分:0)

这是因为您仅获得第一列。您可以通过指定列名称来完成以下操作

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

此外,由于您将所有列都转换为string;我建议使用像List<string>这样的强类型集合,而不要使用ArrayList valuesList = new ArrayList();

答案 4 :(得分:0)

其他答案很好,但是有些担忧

  1. 让我们停止使用ArrayList,而改为使用List<T>
  2. 让我们在可能的地方使用using语句

注意 :我使用ValueTuple返回了多个字段

示例

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));

答案 5 :(得分:0)

最佳做法是先检查阅读器是否有行

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;
    }