C# 我必须删除或改进我的SQL类吗?C

C# 我必须删除或改进我的SQL类吗?C,c#,sql-server,class,C#,Sql Server,Class,我有一个类,它存储我通常用于SQL查询的代码片段 例如,我使用此方法向datagridviews.Datasource填充产品、提供者、客户机等内容,以及我在表中需要的任何数据: public DataTable GetDataTable(string query) { using (SqlConnection _connection = new SqlConnection(ConnectionString)) { _connection.Open();

我有一个类,它存储我通常用于SQL查询的代码片段

例如,我使用此方法向datagridviews.Datasource填充产品、提供者、客户机等内容,以及我在表中需要的任何数据:

public DataTable GetDataTable(string query)
{
    using (SqlConnection _connection = new SqlConnection(ConnectionString))
    {
        _connection.Open();

        using (SqlDataAdapter adapter = new SqlDataAdapter(query, _connection))
        {
            DataTable dt = new DataTable();
            adapter.Fill(dt);

            return dt;
        }
    }
}
我有类似的命令和阅读器。唯一的问题是,对于读卡器,我用SqlDataReader中的第一条记录填充列表,因此我必须在类外运行读卡器来处理组合框之类的事情。为了解决这个问题,我开始认为最好是将查询代码放在需要的地方,而不是创建一个新的ExecuteReader方法来运行Data.SqlClient ExecuteReader方法


我不知道这门课是不是一个好主意,或者我是否在浪费时间试图改进它,有不同的更好的方法来处理这类事情。你觉得怎么样?

我在我的应用程序中也做过类似的事情,有一个集中的地方来发送我的查询,在失败时捕获错误,并返回一个数据表。此后,我改为查询强类型结果集,但前提是相同的

为了扩展现有的内容,您可能希望通过允许传入一个完整的SQLCommand(可能是参数化的)来将其再包装一次。您不希望仅将字符串与

sqlCmd.CommandText = "select .. from .. where x = " + SomeVariableFromUncontrolledSource;
您可能会要求SQL注入

public DataTable GetDataTable(string query)
{
   var sqlcmd = new SqlCommand( query );
   return GetDataTable( sqlcmd );
}

public DataTable GetDataTable(SqlCommand sqlcmd)
{
   using (SqlConnection _connection = new SqlConnection(ConnectionString))
   {
      _connection.Open();
      using (SqlDataAdapter adapter = new SqlDataAdapter(sqlcmd, _connection))
      {
         DataTable dt = new DataTable();
         adapter.Fill(dt);
         return dt;
      }
   }
}

同样,您可能希望包装try/catch这样一个错误的sql连接、错误的查询命令、提供的错误参数、错误的回读等等。。。但是它的好处确实存在,因为它是集中的,并且不会复制打开、关闭的连接以及try/trap错误。通过重载函数以允许使用一个简单的字符串或一个完全准备好的SqlCommand,你们两个都可以到达同一个中心位置。

我在我的应用程序中也做过类似的事情,有一个集中的位置来发送我的查询,在出现故障时捕获错误并返回数据表。此后,我改为查询强类型结果集,但前提是相同的

为了扩展现有的内容,您可能希望通过允许传入一个完整的SQLCommand(可能是参数化的)来将其再包装一次。您不希望仅将字符串与

sqlCmd.CommandText = "select .. from .. where x = " + SomeVariableFromUncontrolledSource;
您可能会要求SQL注入

public DataTable GetDataTable(string query)
{
   var sqlcmd = new SqlCommand( query );
   return GetDataTable( sqlcmd );
}

public DataTable GetDataTable(SqlCommand sqlcmd)
{
   using (SqlConnection _connection = new SqlConnection(ConnectionString))
   {
      _connection.Open();
      using (SqlDataAdapter adapter = new SqlDataAdapter(sqlcmd, _connection))
      {
         DataTable dt = new DataTable();
         adapter.Fill(dt);
         return dt;
      }
   }
}

同样,您可能希望包装try/catch这样一个错误的sql连接、错误的查询命令、提供的错误参数、错误的回读等等。。。但是它的好处确实存在,因为它是集中的,并且不会复制打开、关闭的连接以及try/trap错误。通过重载函数以允许使用一个简单字符串或一个完全准备好的SqlCommand,您可以将两者放在同一个中心位置。

如果您需要一个从数据库返回带有数据的类型化列表的方法,可以执行以下操作:

public List<T> GetList<T>(string query, Func<SqlDataReader, T> func)
{
    var list = new List<T>();

    using (var connection = new SqlConnection(connectionString))
    {
        connection.Open();

        using (var sqlCommand = new SqlCommand(query, connection))
        using (var reader = sqlCommand.ExecuteReader())
        {
            while (reader.Read())
            {
                var item = func(reader);
                list.Add(item);
            }
        }
    }

    return list;
}
也就是说,将创建和填充对象的方法设置为lambda函数。 像这样使用它:

var departments = GetList<Department>(
    "select Id, Name from Department",
    reader => new Department(reader.GetInt32(0), reader.GetString(1)) // using constructor
);

var orders = GetList<Order>(
    "select Id, Price, Date from Order",
    reader => new Order // using properties
    {
        Id = reader.GetInt32(0),
        Price = reader.GetDecimal(1),
        Date = reader.GetDateTime(2)
    }
);

依此类推。

如果您需要一个从数据库返回数据类型列表的方法,您可以执行以下操作:

public List<T> GetList<T>(string query, Func<SqlDataReader, T> func)
{
    var list = new List<T>();

    using (var connection = new SqlConnection(connectionString))
    {
        connection.Open();

        using (var sqlCommand = new SqlCommand(query, connection))
        using (var reader = sqlCommand.ExecuteReader())
        {
            while (reader.Read())
            {
                var item = func(reader);
                list.Add(item);
            }
        }
    }

    return list;
}
也就是说,将创建和填充对象的方法设置为lambda函数。 像这样使用它:

var departments = GetList<Department>(
    "select Id, Name from Department",
    reader => new Department(reader.GetInt32(0), reader.GetString(1)) // using constructor
);

var orders = GetList<Order>(
    "select Id, Price, Date from Order",
    reader => new Order // using properties
    {
        Id = reader.GetInt32(0),
        Price = reader.GetDecimal(1),
        Date = reader.GetDateTime(2)
    }
);

诸如此类。

我建议使用Dapper来阅读数据表。@mjwills昨天我不知道Dapper的存在,我想我会尝试使用它。我建议使用Dapper来阅读数据表。@mjwills昨天我不知道Dapper的存在,我想我会尝试使用它。