2013-02-27 11 views
2

Я использую веб-формы ASP.NET и пытаюсь загрузить данные с SQL-сервера. Вот псевдокод о том, как я это делаю:Сокращение круглых поездок в базу данных

connect1 = connect("database") 
categories = connect.query("select * from category") 
loop categories as category 

    print category   

    connect2 = connect("database") 
    subCategories = connect2.query("select * from subCategory where category = @0", category) 
    loop subCategories as subCategory 

      print subCategory    

      connect3 = connect("database") 
      items = connect3.query("select * from item where subCategory = @0", subCategory) 
      loop items as item 
       print item 
      end loop 'items 
      connect3.close 

    end loop 'subcategories 
    connect2.close 

end loop 'categories 
connect1.close 

Как вы можете видеть, есть много спуско-происходящих в моем сценарии, это хорошо, когда у меня есть только несколько записей, но когда дело с сотнями или больше, это занимает навсегда отображение данных.

Что можно сделать, чтобы уменьшить количество круговых поездок? Я думал о том, чтобы сразу получить все данные из базы данных, а затем классифицировать их в стороне приложения, но возможно ли это?

+0

Сделайте все в одном запросе. Взгляните на [CTE] (http://msdn.microsoft.com/en-us/library/ms190766%28v=sql.105%29.aspx). Этот вопрос лучше подходит для [codereview] (http://codereview.stackexchange.com/) – nunespascal

+0

@nunespascal Почему CTE? – dpp

+0

CTE, чтобы вы могли рекурсивно получить подкатегории. – nunespascal

ответ

2

Почему бы вам не получить все необходимые данные одним запросом с помощью объединений и затем фильтровать на стороне клиента; Или иначе вы можете это сделать (это не так много данных), получая данные как xml, десериализуйте его, чтобы ienumerable перебирать.

Как я вижу вы

categories = connect.query("select * from category"); 

так все, что вам нужно:

whole_data = connect.query("select * from category c inner join subCategory sc on c.id = sc.id inner join item i on i.id = si.id") /*or some kind of*/ 
/*let me think that whole_data is a list of objects, not a dataset*/ 
categories = whole_data.Distinct(d => d.category); 
subCategories = whole_data.Distinct(d => d.subCategories); 
/*and then do your loops*/ 

C# код для ручного отображения может быть таким:

 using (var connection = new SqlConnection(connString)) 
     { 
      connection.Open(); 
      var command = connection.CreateCommand(); 
      command.CommandText = "select * from ..."; 

      var reader = command.ExecuteReader(); 
      while (reader.Read()) 
      { 
       var a = reader.GetInt32(0); 
       var b = reader.GetString(1); 
       /*so basically you read all fields that you get from DB and build object here, then you add it to List or any other kind of collection*/ 
      } 
     } 
+0

Вот что я подумал, но вопрос в том, как? Есть эта вещь, библиотека или класс, которые мне нужны для запроса набора результатов в стороне приложения. – dpp

+0

pseudocoded как я бы это сделал :) – Sergio

+0

Я ценю, что вы пытаетесь помочь, но я не ищу псевдокоды или фактические коды, если вы знаете какую-либо библиотеку или класс, которые я могу использовать для запроса «whole_data», что бы это могло быть? – dpp

1

В зависимости от задержка в вашей базе данных, что делает соединения, даже если они объединены, может занять много времени. Чтобы избежать этого над головой, сделайте все свои соединения за пределами петель. То есть, не устанавливайте соединения. Вместо этого, структура это нравится:

Connect1 = connect("database") 
Connect2 = connect("database") 
Connect3 = connect("database") 

sql 1 nest 
    sql 2 nest 
     sql 3 nest 
     end nest 
    end nest 
end nest 

close connections. 

Если у вас есть 10 записей в цикле, и соединение занимает 10 мс, вы будете тратить 10 х 10 х 10 = 1000 мс просто делают соединения. Возьмите их за пределы гнезда, тогда вы тратите только 30 мс на соединение. Закройте свой datareader при завершении каждого гнезда, чтобы соединение можно было повторно использовать.

Конечно, для примера, который вы показали, выполнение одного запроса является лучшим решением. Но если ваш запрос является выборочным, и вам нужно выполнить некоторую бизнес-логику, которая не может быть объединена в запросе, тогда всегда перемещайте свои соединения за пределы цикла.