creating a database query METHOD

后端 未结 4 1673
旧巷少年郎
旧巷少年郎 2020-12-13 16:24

I\'m not sure if im delluded but what I would like to do is create a method that will return the results of a query, so that i can reuse the connection code. As i understand

4条回答
  •  旧巷少年郎
    2020-12-13 17:25

    The huge problem with the code as you posted it is that there's no way to correctly parameterize the query. You have to do string concatenation before calling your function, and that leaves you open to sql injection attacks. You need a way in your code to allow query parameters to come in separate from the sql string.

    Some other problems in your sample include not correctly closing the connection (it will be left hanging if your query throws an exception) and calling the wrong ADO method.

    I've put a lot of work into getting this right, I think I have something close to the ideal pattern for what you want pretty well nailed in my answer to another question here:
    Fastest method for SQL Server inserts, updates, selects

    Basically, when you call the ADO function to actually run the query, you get back a DbDataReader. I use an iterator block to turn that data reader into an IEnumerable that works nice with linq and other code, and an Action to encourage correct query parameterization. So you abstract out your connection code to a method like this:

    private static IEnumerable Retrieve(string sql, Action addParameters)
    {
        using (var cn = new SqlConnection(ConnectionString))
        using (var cmd = new SqlCommand(sql, cn))
        {
            addParameters(cmd.Parameters);
    
            cn.Open();
            using (var rdr = cmd.ExecuteReader())
            {
                while (rdr.Read())
                    yield return rdr;
                rdr.Close();
            }
        }
    }
    

    And use it in code for the actual queries like this:

    public IEnumerable GetSomeDataById(int MyId)
    {
        return Retrieve(
            "SELECT * FROM [MyTable] WHERE ID= @MyID", 
           p =>
           {
              p.Add("@MyID", SqlDbType.Int).Value = MyId;
           }
         );
    }
    

    Note that this let's you correctly parameterize the query, will always correctly close and dispose of your connections objects, sets you up to do pipelining between each of the layers in a 3-tier or service architecture (makes it fast), and does so with the minimum of code overhead.

提交回复
热议问题