C# getAll 函数咨询

C# getAll Function advice

您好,我正在尝试在 C# 中创建 CRUD 函数,但卡在了我的第一个函数 FetchALL 上,到目前为止它说并非所有代码路径 returns 一个值。

这是我目前的代码

  public SqlDataReader FetchAll(string tableName)
        {  



        using (SqlConnection conn = new SqlConnection(_ConnectionString,))
    { 

    string query = "SELECT * FROM  " + tableName;
    SqlCommand command = new SqlCommand(query, conn);
    using (SqlDataReader reader = command.ExecuteReader())
    conn.Open();


    conn.Close();
           }
        }
    }
}

我可以给你更多信息,谢谢

您需要一个 return 方法声明 return 一个值。

首先,您没有return从该方法中获取任何信息。我要补充一点,您确定要 return SqlDataReader 吗?它是在 using 块中声明的,因此无论如何它都会在您 return 时关闭。我认为你应该重新评估这个函数应该 return.

您有 return 类型的 SqlDataReader,但您没有在代码中的任何地方 returning 任何内容。至少你应该像这样声明你的数据 reader 和 return:

public SqlDataReader FetchAll(string tableName)
{
    SqlDataReader reader;

    using (SqlConnection conn = new SqlConnection(_ConnectionString))
    {

        string query = "SELECT * FROM  " + tableName;

        // added using block for your command (thanks for pointing that out Alex K.)
        using (SqlCommand command = new SqlCommand(query, conn))
        {
            conn.Open(); // <-- moved this ABOVE the execute line.
            reader = command.ExecuteReader(); // <-- using the reader declared above.
            //conn.Close(); <-- not needed.  using block handles this for you.
        }
    }

    return reader;
}

请注意,我还注意到了我看到的其他一些问题,您可以在我的评论中看到这些问题。

此外,我想指出一些非常重要的事情:您应该始终避免在查询中进行字符串连接,因为这会使您面临 SQL 注入攻击的风险(正如 gmiley 适当指出的那样)。在这种情况下,您应该创建一个枚举,其中包含与所有可能的 table 名称关联的值,然后使用字典根据其枚举值查找 table 名称。如果用户提供 invalid/unknown 值,您将抛出参数异常。


尽管如此(正如 Default 指出的那样),您的问题还没有结束。您不能在 using 块中创建连接,它会在退出块后立即处理并关闭,然后使用从该方法 return 编辑的 SqlDataReader。如果我是你,我会 return DataSet 而不是 SqlDataReader。以下是我的做法:

首先,创建可能的 table 值的枚举:

public enum Table
{
    FirstTable,
    SecondTable
}

以及将 table 枚举值映射到 table 名称(您将在静态构造函数中填充)的字典:

private static Dictionary<Table, string> _tableNames = new Dictionary<Table, string>(); // populate this in your static constructor.

然后这是您获取数据的方法:

public static System.Data.DataSet FetchAll(Table fromTable)
{
    var ret = new System.Data.DataSet();

    using (var conn = new System.Data.SqlClient.SqlConnection(_connectionString))
    {
        string tableName = "";
        if (!_tableNames.TryGetValue(fromTable, out tableName)) throw new ArgumentException(string.Format(@"The table value ""{0}"" is not known.", fromTable.ToString()));
        string query = string.Format("SELECT * FROM {0}", tableName);

        using (var command = new System.Data.SqlClient.SqlCommand(query, conn))
        {
            using (var adapter = new System.Data.SqlClient.SqlDataAdapter(command))
            {
                adapter.Fill(ret);
            }
        }
    }

    return ret;
}

最后一点,我建议您根据约定使用小驼峰命名您的 class 级变量,例如_connectionString.