Pull to refresh

Взаимодействие с базой данных на базовом уровне без привлечения специализированных фреймворков.

Reading time6 min
Views9.4K
Этот топик является ответом на это заявление в хабраюзера wizard о том, что проекты для работы с БД на .Net занимают очень много места на диске и вообще, двадцать лет назад трава была зеленее, а деревья выше.
Как высказался один из комментаторов вышеупомянутого топика (neuotq):
чтобы выкопать ямку в песочницы не стоит использовать экскаватор и целую строительную бригаду

Важно понимать, что современные фреймворки дают программисту множество инструментов для решения задач. И если вам нужно, цитирую, «получить пару строк данных» из БД, не нужно для этого применять «комбайны с лазерным прицелом» а-ля ADO.Net Entity Framework или NHibernate. Важно понимать, что такие инструменты созданы для больших проектов. Под большим проектом я понимаю не курсовую или дипломную работу, а крупномасштабные коммерческие системы, которые стоят очень больших денег и лишний «1 день(неделя, месяц)» (опять цитата), затраченный на написание собственных велосипедов, обходится заказчику в сотни(тысячи, миллионы) отнюдь не русских денег. Хороший разработчик отличается от плохого тем, что знает, когда нужно писать велосипед, а когда достаточно взять готовый. Плохой, соответственно, либо пихает кругом фреймворки, либо же наоборот везде пишет велосипеды. И виноваты в этом не инструменты разработчика, а он сам.
Все, не буду утомлять своей философией. Под хабракатом можно почитать о том, как можно взаимодействовать с базой данных в .Net без привлечения экскаваторов.

Итак, если в вашем приложении имеется простая база данных из нескольких таблиц, и вы хотите достичь высокой производительности той пары запросов, которые вам нужно будет выполнять, то совсем не обязательно использовать ADO.Net Entity Framework или что-нибуть соизмеримое. Достаточно будет воспользоваться классами SqlConnection, SqlCommand и SqlDataReader. Для демонстрации напишем простое окошко на WPF:
<Window x:Class="sqlTest.Window1"<br>  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"<br>  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"<br>  Title="Window1" Height="339" Width="783"><br>  <Grid><br>    <Label Height="28" HorizontalAlignment="Left" Name="label1" VerticalAlignment="Top" Width="120">Connection String:</Label><br>    <TextBox Height="23" Margin="126,2,0,0" Name="connStr" VerticalAlignment="Top">Data Source=localhost;Initial Catalog=BlogNetTest;Integrated Security=True;MultipleActiveResultSets=True</TextBox><br>    <TextBox Margin="126,31,0,0" Name="queryTB" AcceptsReturn="True" TextWrapping="Wrap" Height="132" VerticalAlignment="Top">SELECT * FROM Users</TextBox><br>    <Label Height="28" HorizontalAlignment="Left" Margin="0,29,0,0" Name="label2" VerticalAlignment="Top" Width="120">Query:</Label><br>    <TextBox Height="125" Margin="126,0,0,12" Name="resultTB" VerticalAlignment="Bottom" /><br>    <Button Height="23" HorizontalAlignment="Left" Margin="12,0,0,114" Name="button1" VerticalAlignment="Bottom" Width="108" Click="button1_Click">Execute</Button><br>  </Grid><br></Window><br><br>* This source code was highlighted with Source Code Highlighter.

Выглядит оно примерно вот так:

Отлично, теперь напишем код, который будет выполнять запрос и вставлять результат в поле внизу окна:
using System;<br>using System.Data.SqlClient;<br>using System.Text;<br>using System.Windows;<br><br>namespace sqlTest<br>{<br>  public partial class Window1<br>  {<br>    public Window1()<br>    {<br>      InitializeComponent();<br>    }<br><br>    private void button1_Click(object sender, RoutedEventArgs e)<br>    {<br>      try<br>      {<br>        resultTB.Text = ReadData(connStr.Text, queryTB.Text);<br>      }<br>      catch(Exception ex)<br>      {<br>        resultTB.Text = string.Format("Error: {0}", ex.Message);<br>      }<br>    }<br><br>    private static string ReadData(string connectionString, string queryString)<br>    {<br>      var strBuilder = new StringBuilder();<br>      using (var connection =<br>            new SqlConnection(connectionString))<br>      {<br>        var command =<br>          new SqlCommand(queryString, connection);<br>        connection.Open();<br><br>        var reader = command.ExecuteReader();<br><br>        while (reader.Read())<br>        {<br>          for (int i = 0; i < reader.FieldCount; i++)<br>          {<br>            strBuilder.AppendFormat("{0} - {1};", reader.GetName(i), reader[i]);<br>          }<br>          strBuilder.AppendLine();<br>        }<br>        reader.Close();<br>      }<br>      return strBuilder.ToString();<br>    }<br><br>  }<br>}<br><br>* This source code was highlighted with Source Code Highlighter.

Небольшое обьяснение насчет Connection String: эта строка являет собой описание того, как подсоединятся к вашей базе данныx и о том, как ее сформировать для вашей БД можно почитать здесь. Моя строка у вас работать не будет, так как ссылается на локальный SQL Server 2005 Express Edition с тестовой базой одного из моих проектов.
Вот в общем-то и все. Солюшен занимает сотню килобайт на диске и 20 мегабайт памяти при работе. Столь большое количество памяти объясняется использованием WPF, у которого существует минимальный порог использования памяти, около 15 мегабайт. Для проверки этого утверждения я переписал программу для работы в консольном режиме и убедился в том, что он ест около 4 мегабайт. Конечно, это не мало, но и не катастрофически много на сегодняшний день, когда объемы памяти исчисляются гигабайтами. Да, в 1989 году такая программа занимала бы 500 килобайт памяти на машине с 1 Мб ОЗУ (50%). Сейчас она занимает 20 мегабайт на машине с 2 Гб ОЗУ (1%). Но в 1989 году я бы потратил месяц на то, чтобы реализовать даже такую примитивную функциональность, как в примере, а сейчас это получилось всего за 30 минут.
Архив с WPF и консольным проектом
P.S. Извиняюсь за некоторую сумбурность текста, потратил на него всего полтора часа.
UPD: О том, что SQLClient вовсю используется в качестве основы для фреймоворков, которые работают с БД я знаю и не понаслышке — три из трех коммерческих проектов, в разработке которых я принимал участие используют именно его. Статья для студентов, которые не знают о них и упорно используют «экскаваторы для рытья ямок» в своих курсовых/дипломах да еще и ругают дотнет за то, что он видите ли «не дает сделать прямой запрос к БД». Если вы поверхностно пройдетесь по и-нету в поисках того, как средствами дотнета можно работать с БД, то увидите, что 90% материала посвящены ADO.Net Datasets, LINQ2SQL и EF. Собственно, новички и клюют на это, а потом матерятся из-за того, что с самого начала выбрали не тот инструмент, который им нужен.
Tags:
Hubs:
+36
Comments51

Articles