C#从一个类向另一个类发送选择命令并返回结果?

时间:2018-10-03 12:53:26

标签: c# sql-server

我是C#的初学者,所以这个问题可能有点愚蠢,但是...

我想将一些SQL命令作为字符串从一个类发送到另一个类,执行然后将结果返回给第一类。

    class MainWindow
private void btnLogin_Click(object sender, RoutedEventArgs e)
        {

            TestConnection checkLogin = new TestConnection();
            checkLogin.SimpleQuery("SELECT Name FROM Names WHERE ID='1'", "");

            //MessageBox .Show(checkLogin.SimpleQuery(response:ToString));
        }

和TestConnection类

  public string SimpleQuery(string request, string response)
    {


        using (SqlConnection conn = new SqlConnection())
        {
            conn.ConnectionString = "Server=SQLOLEDB.1;User ID=" +
                Constants.DATABASE_USERNAME + ";Password=" +
                Constants.DATABASE_PASSWORD + ";Initial Catalog=" +
                Constants.DATABASE_CATALOG + ";Data Source=" +
                Constants.SERVER_ADRESS;

            SqlCommand command = new SqlCommand(request, conn);

            {
                conn.Open();
                response = Convert.ToString (command.ExecuteScalar());
                conn.Close();
                return response; 
            }

        }

像这样的东西甚至可以吗? 我正在学习,正在测试想法。

谢谢!

3 个答案:

答案 0 :(得分:2)

问题是,通常您希望类封装功能。

对于您来说,如果将查询保留在对象中并公开名称与实际功能相对应的方法,则更有意义,例如:

//your class, also: the name must describe it's reason for existence
public class UserRepository { //previously known as TestConnection

//the method name explains its function.
//the query is stored within the function
//therefore the functionality is encapsulated
public string CheckLogin(int id)
{
    //note: tricky: almost SQL injection here: that must be fixed.
    //I just left it here so you can see the basic idea
    var request = "SELECT Name FROM Names WHERE ID ="  + id.ToString();

    //another note: response doesn't have to be passed as parameter.
    var response = string.Empty;
    using (SqlConnection conn = new SqlConnection())
    {
        conn.ConnectionString = "Server=SQLOLEDB.1;User ID=" +
            Constants.DATABASE_USERNAME + ";Password=" +
            Constants.DATABASE_PASSWORD + ";Initial Catalog=" +
            Constants.DATABASE_CATALOG + ";Data Source=" +
            Constants.SERVER_ADRESS;

        SqlCommand command = new SqlCommand(request, conn);
        {
            conn.Open();
            response = Convert.ToString (command.ExecuteScalar());
            conn.Close();
            return response; 
        }
    }

可以进行一些进一步的增强,但是现在我认为这将使您有足够的思考空间。


SQL注入问题(请参阅注释)

要防止SQL注入,一个好的方法是使用参数。 here上有一篇文章。

基本上,它取决于使用参数化输入:

免责声明:复制自链接:

 using (SqlCommand command = 
              new SqlCommand("SELECT * FROM Dogs1 WHERE Name LIKE @Name", connection))
 {
     // Add new SqlParameter to the command.
     command.Parameters.Add(new SqlParameter("Name", dogName));

有关如何以及为什么的更多信息,请参见this link

答案 1 :(得分:2)

这是一个有效的示例,其中包含针对非参数化sql的修复程序以及有关如何更好地存储连接字符串的建议。

MainWindow.cs

class MainWindow
{
    private void btnLogin_Click(object sender, RoutedEventArgs e)
    {
        SomeRepository repo = new SomeRepository();
        var userName = repo.GetUserName(1);
        MessageBox.Show(userName ?? "User not found!");
    }
}

SomeRepository.cs

public sealed class SomeRepository
{
    private readonly string connectionString;
    public SomeRepository()
    {
      // the ideal location for a connection string is in the application's app.config (or web.confic)
      connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString;

      // Or uncomment this
      // connectionString = "Server=SQLOLEDB.1;User ID=" +
        //      Constants.DATABASE_USERNAME + ";Password=" +
        //      Constants.DATABASE_PASSWORD + ";Initial Catalog=" +
        //      Constants.DATABASE_CATALOG + ";Data Source=" +
        //      Constants.SERVER_ADRESS;
    }

    public string GetUserName(int id)
    {
        const string sqlRequest = "SELECT Name FROM Names WHERE ID = @id";

        using (SqlConnection conn = new SqlConnection(this.connectionString))
        using (SqlCommand command = new SqlCommand(sqlRequest, conn))
        {
            // if this is an integer in the schema, which it looks like it should be, then you need to pass it as an int and not a string
            command.Parameters.Add("@id", SqlDbType.Int).Value = id;

            // if it is a string then specify the type as varchar and specify the varchar length in the schema and pass a string
            // command.Parameters.Add("@id", SqlDbType.VarChar, 20).Value = id.ToString();

            conn.Open();
            return command.ExecuteScalar()?.ToString();
        }
    }
}

app.config

<?xml version="1.0"?>
<configuration>

  <connectionStrings>
    <add name="MyConnection" connectionString="YOUR CONNECTION STRING HERE" providerName="System.Data.SqlClient"/>
  </connectionStrings>

</configuration>

答案 2 :(得分:0)

您必须存储/config的返回结果,才能最终在MessageBox中显示该结果。

SimpleQuery()

更改您的方法以返回结果:

    private void btnLogin_Click(object sender, RoutedEventArgs e)
    {
        TestConnection checkLogin = new TestConnection();
        string result = checkLogin.SimpleQuery("SELECT Name FROM Names WHERE ID='1'", "");

        MessageBox.Show(result);
    }