2013-11-27 4 views
1

Я разрабатываю решение C# с доступом к данным Oracle.Query & generic

И хотел бы иметь общее решение о запросе.

Вот часть моего кода:

public DataTable GetData(string query) 
{ 
    DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.OracleClient"); 

    using (DbConnection conn = factory.CreateConnection()) 
    { 
     try 
     { 
      DbConnectionStringBuilder csb = factory.CreateConnectionStringBuilder(); 
      csb["Data Source"] = @"Northwind"; 
      csb["User Id"] = @"Northwind"; 
      csb["Password"] = @"Northwind"; 

      conn.ConnectionString = csb.ConnectionString; 
      conn.Open(); 

      using (DbCommand cmd = conn.CreateCommand()) 
      { 
       cmd.CommandText = query; 

       using (DataTable dt = new DataTable()) 
       { 
        DbDataAdapter da = factory.CreateDataAdapter(); 
        cmd.CommandType = CommandType.Text; 
        da.SelectCommand = cmd; 
        da.Fill(dt); 
        return dt; 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      throw new Exception("Error", ex); 
     } 
     finally 
     { 
      if (conn.State != ConnectionState.Closed) 
       conn.Close(); 
     } 
    } 
} 

И я называю мой метод, как это:

DataAccess.Provider data = new DataAccess.Provider(); 
DataTabel dt = dt.GetData("select * from myTable); 

Это работает довольно хорошо, но это не моя цель.

У меня есть второй класс под названием CL_mpg со всеми моими SQL-запросами.

class CL_MPG 
{ 
    public string rq_sql; 

    public string selectParam(string param) 
    { 
     this.rq_sql = "select * from myTable where id = '" + param + "';"; 
     return this.rq_sql; 
    } 

    public string select() 
    { 
     this.rq_sql = "select * from myTable"; 
     return this.rq_sql; 
    } 

    //... 

} 

И я хотел бы использовать мои методы selectParam и/или select заполнить мою DataTable, но я не знаю, как сделать это.

+1

Любая причина, по которой вы переворачиваете свой собственный DAL, в отличие от использования существующей структуры? – Stijn

+0

Я не могу использовать фреймворк, школьный проект – Shrimp

+4

@Shrimp пока вы используете классы BCL (.NET Framework) ... зачем рисовать произвольную строку? Также: * параметры *; никогда не объединяйте значения в SQL. Если вы узнаете ** одно: ** этот термин, узнайте об этом. –

ответ

0

Хотя другие жалуются на вашу попытку обучения, каждый должен начать где-то. Ваш метод на самом деле хорошо начат, но я бы изменил параметр из строки на объект DbCommand. Затем вы можете создать свои методы для правильной сборки команды и установки правильных параметров. Затем передать всю подготовленную команду в метод обертки (что создает соединения, тесты открытых успешно, данные запросы, и т.д.), и ваш метод возвращает DataTable объекта, как у вас есть ... что-то вроде

public class CL_MPG 
{ 
    private DataTable GetData(DbCommand cmd) 
    { 
     // do all the same as you have with exception of your USING DBCOMMAND. 
     // just set the connection property of the incoming command to that of 
     // your connection created 
     // AT THIS PART -- 
     // using (DbCommand cmd = conn.CreateCommand()) 
     // { 
     // cmd.CommandText = query; 
     // just change to below and remove the closing curly bracket for using dbcommand 
     cmd.Connection = conn; 
    } 

    // Now, your generic methods that you want to expose for querying 
    // something like 
    public DataTable GetAllData() 
    { 
     DbCommand cmd = new DbCommand("select * from YourTable"); 
     return GetData(cmd); 
    } 

    public DataTable GetUser(int someIDParameter) 
    { 
     DbCommand cmd = new DbCommand("select * from YourTable where ID = @parmID"); 
     cmd.Parameters.Add("@parmID", someIDParameter); 
     return GetData(cmd); 
    } 

    public DataTable FindByLastName(string someIDParameter) 
    { 
     DbCommand cmd = new DbCommand("select * from YourTable where LastName like @parmTest"); 
     cmd.Parameters.Add("@parmTest", someIDParameter); 
     return GetData(cmd); 
    } 
} 

Обратите внимания на команде строится и полностью подготовлен и параметризирован, а также конкатенация строк, поскольку был сделан предварительный комментарий, который может предоставить вам SQL-инъекцию. Что касается параметров, а не запросов Oracle, их, возможно, придется немного подстроить. Различные двигатели используют несколько разные соглашения. При подключении к базе данных SQL-Server он использует «@» для идентификации параметра. В базе данных SyBase Advantage используется «:». Используя Visual FoxPro, просто «?» используется заполнитель.

Кроме того, если ваш запрос имеет много критериев, просто добавьте дополнительные заполнители типа «@parm», затем добавьте свои параметры в том же порядке, в каком они появляются в вашем запросе, чтобы убедиться, что вы его не пропустили. Некоторые функции могут не иметь ни одного, ни одного из них в зависимости от ваших потребностей. Затем в представленных образцах это так же просто, как делать что-то вроде

DataTable whoIs = yourCL_MPGObject.GetUser(23); 
if(whoIs.Rows.Count > 0) 
    MessageBox.Show(whoIs.Rows[0]["WhateverColumnName"]);