我的方法是使用正确的类来查询数据库吗?

我的方法是使用正确的类来查询数据库吗?

问题描述:

我是相当新的编程世界。我试图自己学习编程,所以如果有人能让我知道我的方法是否正确,我将不胜感激。我的方法是使用正确的类来查询数据库吗?

我想创建一个类(用C#),它可以用来在MS-SQL数据库上运行查询。由于我刚刚开始使用ADO.net。因此,我没有在代码中使用如此多的DB语句,而是决定创建一个用于查询数据库的类。

我创建了一个类Dbclass,并在select类中创建了一个方法 - SelectQuery,它返回一个Dataset。

以下更清晰的是我创建的类。

public class Dbclass 
{ 
    private SqlConnection DBcon = null; 
    private string ConStr = ""; 

    public Dbclass(string Constring) 
    { 
     this.ConStr = Constring; 
     DBcon = new SqlConnection(this.ConStr); 
    } 

    public DataSet SelectQuery(string[] coloumns,string[] tables,string cond) 
    { 
     string col = string.Join(",", coloumns); 
     string tbl = string.Join(",", tables); 
     string selectSQL = "SELECT " + col + " FROM " + tbl + cond; 
     SqlCommand cmd = new SqlCommand(selectSQL, this.DBcon); 
     SqlDataAdapter ada = new SqlDataAdapter(); 
     DataSet retrnds = new DataSet(); 
     try 
     { 
      this.DBcon.Open(); 
      ada.SelectCommand = cmd; 
      ada.Fill(retrnds); 
     } 
     catch (Exception err) 
     { 
      string error = err.ToString(); 
     } 
     finally 
     { 
      this.DBcon.Close(); 
     } 
     return retrnds; 
    } 
} 

所以我的问题是,我做正确的事情,作为一个初学者来创建这样一个类?我的面向对象方法是否正确?

如果有人能指导我采取更好的方法,那将会很好。

+0

是的,当然,我自己使用这种方法:即在一个类中存储连接字符串和查询方法。 – Taosique

+2

你看过LINQ吗? – Andrew

+0

您的解决方案对SQL注入开放。 http://en.wikipedia.org/wiki/SQL_injection。阅读本文http://www.codinghorror.com/blog/2005/04/give-me-parameterized-sql-or-give-me-death.html –

是总体是好的,这是提高的标志几件事情:并不意味着

public Dbclass(string Constring) 
    { 
     this.ConStr = Constring; 
     DBcon = new SqlConnection(this.ConStr); 
    } 

连接对象被重用。当然,它可以节省您的时间和代码。但是,当你不再需要它们时,你真的想要创建一个新的Connnection实例并将它们添加进去。

而且这样的:

try 
    { 
     //....... 
    } 
    catch (Exception err) 
    { 
     string error = err.ToString(); 
    } 
    finally 
    { 
     this.DBcon.Close(); 
    } 

这是确定你知道的,但.NET 4要采取IDisposable的,在这里你不必手动配置连接的优势。

public DataSet SelectQuery(string[] coloumns,string[] tables,string cond) 
{ 
    using (SqlConnection DBcon= new SqlConnection(this.ConStr)) 
    { 
     string col = string.Join(",", coloumns); 
     string tbl = string.Join(",", tables); 
     string selectSQL = "SELECT " + col + " FROM " + tbl + cond; 
     SqlCommand cmd = new SqlCommand(selectSQL, this.DBcon); 
     SqlDataAdapter ada = new SqlDataAdapter(); 
     DataSet retrnds = new DataSet(); 
     try 
     { 
      this.DBcon.Open(); 
      ada.SelectCommand = cmd; 
      ada.Fill(retrnds); 
     } 
     catch (Exception err) 
     { 
      string error = err.ToString(); 
     } 
     //no need for this.DBcon.Close(); 

     return retrnds; 
    } 
}  

对于您的问题没有正确的答案,但这是我使用的。

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Data.OleDb; 
using System.Linq; 
using System.Text; 

namespace Core.DataAccess.OleDb 
{ 
    public static class DataInterface 
    { 
     public static DataTable DoRead(string connectionString, string commandText) 
     { 
      return DoRead(connectionString, commandText, new OleDbParameter[] { }); 
     } 

     public static DataTable DoRead(string connectionString, string commandText, OleDbParameter[] parameters) 
     { 
      OleDbConnection connection = new OleDbConnection(connectionString); 

      OleDbCommand command = new OleDbCommand(commandText, connection); 

      foreach (OleDbParameter p in parameters) 
      { 
       command.Parameters.Add(p); 
      } 

      OleDbDataAdapter dataAdapter = new OleDbDataAdapter(command); 

      DataTable table = new DataTable(); 
      table.Locale = System.Globalization.CultureInfo.InvariantCulture; 
      dataAdapter.Fill(table); 
      return table; 
     } 

     public static void DoWrite(string connectionString, string commandText) 
     { 
      DoWrite(connectionString, commandText, new OleDbParameter[] { }); 
     } 

     public static void DoWrite(string connectionString, string commandText, OleDbParameter[] parameters) 
     { 
      OleDbConnection connection; 
      OleDbTransaction transaction; 

      connection = new OleDbConnection(connectionString); 
      connection.Open(); 

      transaction = connection.BeginTransaction(); 

      OleDbCommand command = new OleDbCommand(commandText, connection); 

      foreach (OleDbParameter p in parameters) 
      { 
       command.Parameters.Add(p); 
      } 

      try 
      { 
       command.Transaction = transaction; 
       command.ExecuteNonQuery(); 
      } 
      finally 
      { 
       transaction.Commit(); 
       connection.Close(); 
      } 
     } 

     public static OleDbParameter CreateOleDbParameter(string name, OleDbType type, object value) 
     { 
      OleDbParameter parameter = new OleDbParameter(); 
      parameter.OleDbType = type; 
      parameter.ParameterName = name; 
      parameter.Value = value; 
      return parameter; 
     } 
    } 
} 

您将每个方法的连接字符串,参数化SQL查询和可选参数传递给每个方法。

var connectionString = "my connection string"; 
var commandText = "INSERT INTO Person (ID, Name, Age) VALUES (?, ?, ?)"; 

var parameters = new List<OleDbParameter>(); 
parameters.Add(new OleDbParameter { Value = "12345" }); // id 
parameters.Add(new OleDbParameter { Value = "Joe Bloggs" }); // name 
parameters.Add(new OleDbParameter { Value = 35 }); // age 

Core.DataAccess.OleDb.DataInterface.DoWrite(connectionString, commandText, parameters.ToArray()); 
+0

感谢您的输入。但是在这种情况下,如果有多个插入到不同的表或选择语句,难道你不认为代码中会有很多sql语句,我试图通过创建一个类来避免。 –

在我看来,最好是使用ORM方法。您可以像程序中的普通对象一样使用实体,并且与SQL注入攻击相比,它更加安全。

我们在我们的项目中使用实体,它让我的生活变得非常简单。例如,如果我想找回富人的名单:

var minimumSalary = 10000; 
var richPeople = database.People.Where(o => o.Salary > minimumSalary).ToList(); 
+0

我也会使用ORM。 – Brian