2009-03-31 2 views
3

Это будет очень просто, я знаю. Я видел так много разных способов использования sql в asp.net без реального стандарта. Я хочу знать, как правильно выбрать из базы данных sql в asp.net и получить несколько записей. Например: выберите всех пользователей.Asp.Net select in Sql

String sql = 
    "SELECT [UserId] FROM [UserProfiles] WHERE NOT [UserId] = 'CurrentUserId'"; 

string strCon = System.Web 
         .Configuration 
         .WebConfigurationManager 
         .ConnectionStrings["SocialSiteConnectionString"] 
         .ConnectionString; 

SqlConnection conn = new SqlConnection(strCon); 
SqlCommand comm = new SqlCommand(sql, conn); 
conn.Open(); 

/* 
This is where I need to know how to retrieve the information from the 
above command(comm). I am looking for something similiar to php's 
mysql_result. I want to access the records kind of like an array or some 
other form of retrieving all the data. 
Also when the new SqlCommand is called...does that actual run the 
SELECT STATEMENT or is there another step. 
*/ 

conn.Close(); 
+0

+1 для SqlCommand для предотвращения инъекций. – jww

ответ

6

Я думаю, что это то, что вы ищете.

String sql = "SELECT [UserId] FROM [UserProfiles] WHERE NOT [UserId] = 'CurrentUserId'"; 

string strCon = System.Web 
         .Configuration 
         .WebConfigurationManager 
         .ConnectionStrings["SocialSiteConnectionString"].ConnectionString; 

SqlConnection conn = new SqlConnection(strCon); 
SqlCommand comm = new SqlCommand(sql, conn); 
conn.Open(); 
SqlDataReader nwReader = comm.ExecuteReader(); 
while (nwReader.Read()) 
{ 
    int UserID = (int)nwReader["UserID"]; 
    // Do something with UserID here... 
} 
nwReader.Close(); 
conn.Close(); 

Я должен сказать, однако, что общий подход может использовать множество настроек. Во-первых, вы могли бы, по крайней мере, начать с упрощения доступа к вашему ConnectionString. Например, можно добавить следующие строки в ваш файл Global.asax.cs:

using System; 
    using System.Configuration; 

    public partial class Global : HttpApplication 
    { 
     public static string ConnectionString; 

     void Application_Start(object sender, EventArgs e) 
     { 
      ConnectionString = ConfigurationManager.ConnectionStrings["SocialSiteConnectionString"].ConnectionString; 
     } 
     ... 
    } 

Теперь, на протяжении всего кода, просто получить доступ к нему с помощью:

SqlConnection conn = new SqlConnection(Global.ConnectionString); 

еще лучше, создать класс, в котором «сантехника» скрыта. Для того, чтобы запустить тот же запрос в моем коде, я бы просто ввести:

 using (BSDIQuery qry = new BSDIQuery()) 
     { 
      SqlDataReader nwReader = qry.Command("SELECT...").ReturnReader(); 
      // If I needed to add a parameter I'd add it above as well: .ParamVal("CurrentUser") 
      while (nwReader.Read()) 
      { 
       int UserID = (int)nwReader["UserID"]; 
       // Do something with UserID here... 
      } 
      nwReader.Close(); 
     } 

Это просто пример использования мой DAL. Однако обратите внимание, что нет строки подключения, не созданных или управляемых объектов или соединений, а просто «BSDIQuery» (в дополнение к тому, что показано на рисунке). Ваш подход будет отличаться в зависимости от задач, которые вы выполняете чаще всего.

+0

Это отлично поработало, это именно то, что я искал! – user84786

+0

Это довольно плохо, хотя с точки зрения надежности: исключения будут оставлены зависающими, если есть исключения, даже если вы поймаете исключение. –

+0

Joel - см. Дополнительный код, который я ввел. Я согласен с вами, но хотел ответить на «основной» вопрос, прежде чем переходить к более глубоким вопросам. –

1

Создание SqlCommand не выполняет его вообще.

Эта команда будет выполнена при вызове ExecuteReader или что-то подобное.

Если вы хотите получить что-нибудь, что принесет все результаты в память, вы должны смотреть на DataSet/DataTable. Для них есть учебное пособие here - или в сети много других, и любая достойная книга ADO.NET также их охватит.

Если вы не хотите получить их все в память сразу, то ExecuteReader это метод для вас. Это вернет SqlDataReader, который похож на курсор базы данных - он читает строку за раз, и вы запрашиваете отдельные столбцы по своему желанию, вызывая Read для перехода к следующей строке каждый раз.

+0

Я действительно не хочу получать результаты в память, как вы получаете доступ к результатам после вызова ExecuteReader? – user84786

3

Большую часть времени я использую это (обратите внимание, что я также с использованием пула подход подключения):

public DataTable ExecuteQueryTable(string query) 
    { 
     return ExecuteQueryTable(query, null); 
    } 

    public DataTable ExecuteQueryTable(string query, Dictionary<string, object> parameters) 
    { 
     using (SqlConnection conn = new SqlConnection(this.connectionString)) 
     { 
      conn.Open(); 

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

       if (parameters != null) 
       { 
        foreach (string parameter in parameters.Keys) 
        { 
         cmd.Parameters.AddWithValue(parameter, parameters[parameter]); 
        } 
       } 

       DataTable tbl = new DataTable(); 
       using (SqlDataAdapter da = new SqlDataAdapter(cmd)) 
       { 
        da.Fill(tbl); 
       } 

       return tbl; 
      } 
     } 
    } 
+0

Это хорошо ... но я бы хотел, чтобы он принимал IEnumerable , а не словарь, вы можете складывать свои операторы использования, чтобы избежать глубокого вложения, было бы неплохо иметь способ избежать предоставления .Net выведите тип своих параметров, и вы можете использовать DataTable.Load, а не .Fill –

+0

Мне нравится. Заполните, потому что мне лучше. И причина, по которой я использую такие приложения, как я, это потому, что я запускаю StyleCop на все. И я согласен с IEnumerable . –

2

Вот адаптация существующего кода:

String sql = "SELECT [UserId] FROM [UserProfiles] WHERE [UserId] != @CurrentUserId"; 

string strCon = System.Web 
         .Configuration 
         .WebConfigurationManager 
         .ConnectionStrings["SocialSiteConnectionString"].ConnectionString; 

DataTable result = new DataTable(); 
using (var conn = new SqlConnection(strCon)) 
using (var cmd = new SqlCommand(sql, conn)) 
{ 
    cmd.Parameters.Add("@CurrentUserID", SqlDbType.Int).Value = CurrentUserID; 
    conn.Open(); 

    result.Load(cmd.ExecuteReader()); 
} 
0

В то время как в PHP вы могли бы сделать что-то вроде,

while ($row = mysql_fetch_array ($result)) 
{ 
    //this assumes you're doing something with foo in loop 
    $foo = $row["userid"]; 

    //using $foo somehow 
} 

в .NET, вы делаете что-то другое. Поверьте мне, исходя из PHP-фона, переход с PHP на .NET непросто. Есть много вещей, которые кажутся странными. Через некоторое время это будет иметь смысл! Просто придерживайтесь его. Лично мне это нравится.

Ok ..если у вас есть набор данных, как вы говорите, вы можете сделать что-то вроде этого,

//assuming you have a DataSet called myDataSet 
for (int i = 0; i < myDataSet.Tables[0].Rows.Count; i++) 
{ 
    //likewise assuming here you're doing something with foo in loop 
    string foo = myDataSet.Tables[0].Rows[i]["userid"].ToString(); 

    //similarly do something with foo in loop 
} 

Это делает то же самое, что и PHP сниппета.

+0

Оба плохие. Почему вы должны устанавливать одну и ту же переменную снова и снова? Если вы хотите использовать это для выполнения какой-либо другой работы внутри цикла, добавьте комментарий к фрагментам кода, чтобы сделать это более очевидным. –

+0

Хороший улов. Это было совершенно очевидно для меня, когда я печатал его.) Да, я предполагал, что вы будете что-то делать с этими переменными в цикле. – Anjisan