Query & generic
Я разрабатываю решение C# с доступом к данным в Oracle.
И хотел бы иметь общее решение о запросе.
Вот часть моего кода:
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
чтобы заполнить мои данные, но я не знаю, как это сделать.
1 ответ
Хотя другие жалуются на ваши попытки учиться, все должны с чего-то начинать. Ваш метод на самом деле хороший старт, но я бы изменил параметр из строки в объект 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"] );