<?xml version="1.0" encoding="UTF-8"?>

<rss version="2.0"
 xmlns:blogChannel="http://backend.userland.com/blogChannelModule"
>

<channel>
<title>&#x412;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x430; &#x42D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;!</title>
<link>http://maillist.ru/55140</link>
<description>&#x412; &#x43D;&#x430;&#x448;&#x435;&#x439; &#x440;&#x430;&#x441;&#x44B;&#x43B;&#x43A;&#x435; &#x432;&#x44B; &#x443;&#x437;&#x43D;&#x430;&#x435;&#x442;&#x435; &#x43E; &#x440;&#x430;&#x437;&#x43B;&#x438;&#x447;&#x43D;&#x44B;&#x445; &#x442;&#x43E;&#x43D;&#x43A;&#x43E;&#x441;&#x442;&#x44F;&#x445;, &#x43D;&#x44E;&#x430;&#x43D;&#x441;&#x430;&#x445; &#x438; &#x442;&#x440;&#x44E;&#x43A;&#x430;&#x445; &#x432;&#x435;&#x431;-&#x434;&#x438;&#x437;&#x430;&#x439;&#x43D;&#x430;, &#x432;&#x435;&#x431;-&#x43F;&#x440;&#x43E;&#x433;&#x440;&#x430;&#x43C;&#x43C;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x44F; &#x438; &#x432;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x438; &#x432; &#x446;&#x435;&#x43B;&#x43E;&#x43C;. &#x41E;&#x445;&#x432;&#x430;&#x442; &#x442;&#x435;&#x43C; &#x43E;&#x447;&#x435;&#x43D;&#x44C; &#x448;&#x438;&#x440;&#x43E;&#x43A; - &#x43E;&#x442; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x44B; &#x432; &#x433;&#x440;&#x430;&#x444;&#x438;&#x447;&#x435;&#x441;&#x43A;&#x438;&#x445; &#x440;&#x435;&#x434;&#x430;&#x43A;&#x442;&#x43E;&#x440;&#x430;&#x445;, &#x434;&#x43E; &#x43F;&#x440;&#x43E;&#x433;&#x440;&#x430;&#x43C;&#x43C;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x44F; &#x43F;&#x43E;&#x434; AJAX &#x438; ASP.NET.</description>
<language>ru</language>

<item>
<title>&#x412;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x430;? &#x42D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;! &#x418;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x443;&#x435;&#x43C; &#x441;&#x435;&#x440;&#x432;&#x438;&#x441; Gravatar
</title>
<link>http://archives.maillist.ru/55140/1466114.html?rss=1</link>
<description><![CDATA[<style type="text/css"><!-- p { 
     padding-left: 10px; 
     padding-right: 10px; 
     font: 14px/20px Veradana, Arial, sans-serif; 
} 
 
span.drop { 
     font: bold 60px /0.83em tahoma, sans-serif; 
     color: #0019ff; 
     float: left; 
     margin-right: 5px; 
     margin-top: 5px; 
} 
 
 .list { 
     background-color: #f5f5f5; 
     border: 1px solid #ededed; 
     padding: 10px; 
     margin: 10px 40px 10px 40px; 
     font-family: courier, monospace; 
} 
 
h1{ 
     font-family: Verdana, Arial, Sans-Serif; 
     color:#fcb300; 
     font-size:28px; 
     font-weight:bold; 
     padding: 10px 0 0 10px; 
     text-align:left; 
} 
 --></style>
    
<table width="100%" summary="" cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" style="background-color: #ffffff; background-image: ;">
<tr valign="top" align="left">
<td bgcolor="#ffffff" style="padding: 5px; background-color: #ffffff; background-image: ;"><h1>Используем сервис Gravatar</h1>
<p>Название Gravatar переводится как "глобально распознаваемые аватары", и предназначен для хранения и глобального доступа к аватаркам пользователя и его персональным данным.</p>

<p>Все URL-ы в системе gravatar имеют одну общую ключевую деталь - хеш адрсеса электропочты пользователя. Именно этот хеш уникально идентифицирует пользователя в рамках сервиса gravatar. Хеш формируется очень просто. Для этого нужно взять e-mail, убедиться, что в нем отсутствуют начальные и конечные пробелы, привести его в нижний регистр, и взять MD5-хеш полученной строки.</p>

<p>На языке PHP этот код будет выглядеть так:</p>

<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><div id="lc1"><span style="color: #19177C">$email</span> <span style="color: #666666">=</span> <span style="color: #BA2121">&quot;vgrinin@gmail.com&quot;</span>;
</div><div id="lc2"><span style="color: #008000; font-weight: bold">echo</span> <span style="color: #008000">md5</span>(<span style="color: #008000">strtolower</span>(<span style="color: #008000">trim</span>(<span style="color: #19177C">$email</span>)));
</div></pre></div>

<p>А на C# - вот так:</p>

<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><div id="lc1"><span style="color: #B00040">string</span> email = <span style="color: #BA2121">&quot;vgrinin@gmail.com&quot;</span>;
</div><div id="lc2"><span style="color: #B00040">byte</span>[] hash = MD5.Create().ComputeHash(Encoding.Default.GetBytes(
</div><div id="lc3">  email.Trim().ToLower()));
</div><div id="lc4">StringBuilder hashString = <span style="color: #008000; font-weight: bold">new</span> StringBuilder();
</div><div id="lc5"><span style="color: #008000; font-weight: bold">for</span> (<span style="color: #B00040">int</span> i = <span style="color: #666666">0</span>; i &amp;lt; hash.Length; i++)
</div><div id="lc6">{
</div><div id="lc7">  hashString.Append(hash[i].ToString(<span style="color: #BA2121">&quot;X2&quot;</span>));
</div><div id="lc8">}
</div><div id="lc9">Console.WriteLine(hashString.ToString().ToLower());
</div></pre></div>
<p style="padding: 0; margin: 2em 0 1em 0; font-size: 0.8em; color: #666;"><span style="padding: 0 1em; background-color: #f5f5f5;"> Colored with <a style="color: #333" href="http://dumpz.org">dumpz.org</a></span></p>

<p>Гм... получилось несколько длиннее, чем на PHP.</p>

<p>Протестируйте работу алгоритма, введите свой e-mail в поле ввода ниже и нажмите кнопку "Преобразовать" <a href="http://easy4web.ru/?p=1207#test">здесь</a>.

<p>Ну что же, теперь все готово, чтобы, используя полученный хеш, запросить с сервера gravatar изображение аватарки или профиль пользователя. Начнем с аватарки.</p>

<p>В самом простейшем случае запросить аватарку можно при помощи URL-а: http://www.gravatar.com/avatar/HASH. Здесь HASH - это MD5-хеш, полученный из e-mail на предыдущем шаге. Ответом на этот запрос явится изображение, которое можно отобразить на странице при помощи тега IMG, таким образом: 
<em>&lt;img src="http://www.gravatar.com/avatar/HASH" /&gt;</em></p>

<p>Например, для меня (vgrinin@mail.ru) это будет выглядеть так:<br/>
<em>&lt;img src="http://www.gravatar.com/avatar/b902d209d0efede9d9113a03c4ccb756" /&gt;</em></p>

<p>По умолчанию, изображение идет в PNG-формате, но если вы хотите получить его например в JPG, то нет ничего проще - добавьте расширение в конце URL, вот так:<br/>
<em>&lt;img src="http://www.gravatar.com/avatar/b902d209d0efede9d9113a03c4ccb756.jpg" /&gt;</em></p>

<p>При помощи параметра s мы можем указать размер изображения в пикселях, от 1 до 512, вот так:<br/>
<em>&lt;img src="http://www.gravatar.com/avatar/b902d209d0efede9d9113a03c4ccb756.jpg?s=200" /&gt;</em></p>

<p>Размер задается только один, так как аватарки у gravatar`а - квадратные. Если сервис не находит картинки, то он отображает изображение по умолчанию. Если мы хотим задать какое-то конкретное изображение по умолчанию, то укажем его в параметре d, вот так:<br/>
<em>&lt;img src="http://www.gravatar.com/avatar/b902d209d0efede9d9113a03c4ccb756.jpg?s=200&d=http%3A%2F%2Fmyserver.ru%2Fimages%2Fdefault.jpg" /&gt;</em></p>

<p>Как видим, здесь просто задается полный URL до изображения, причем URL-encoded. Существует также ряд предопределенных значений параметра d, при этом изображение по умолчанию будет взято(сгенерировано) из одного из стандартных рядов изображений по умолчанию:

<ol>
<li><em>mm</em>: человек-загадка, стандартное изображение человеческого силуэта (не изменяемое в зависимости от хеша)</li>
<li><em>identicon</em>: абстрактная геометрическая фигура, сгенерированная в зависимости от хеша</li>
<li><em>monsterid</em>: "уродцы", созданные из хеша, с разными лицами, цветов и т.д.</li>
<li><em>wavatar</em>: лица-иконки, созданные из хеша, с разной формой, ыветом и т.д.</li><li>
<em>retro</em>: 8-битные упрощенные лица-иконки</li>
</ol>
</p>

<p>Попробуйте введите в поле формы <a href="http://easy4web.ru/?p=1207#test2">здесь</a> любую строку и посмотрите, какие варианты изображений по умолчанию создаст для вас сервис gravatar. А если ввести зарегистрированный в gravatar e-mail, то все 5 изображений будут одинаковыми и представлять собой не случайное изображение по умолчанию, а ваш собственный аватар.</p>

<p>Разберемся с еще одним URL-аргументом - <strong>r</strong>. Параметр r позволяет задать рейтинг отображаемого изображения. Что это значит? При регистрации в gravatar, пользователь может загрузить не одно, а несколько разных изображений. Каждое из них имеет свой, определяемый самим пользователем рейтинг:

<ul>
<li>Граватары с ретингом G пригодны для показа на сайтах с любой аудиторией. </li>
<li>Граватары с рейтингом PG могут содержать неприличные жесты, провокационно одетых людей, грубые выражения или умеренную жестокость. </li>
<li>Граватары с рейтингом R могут быть оскорбительными, содержать сцены жестокости, обнаженные тела или связанные с наркотиками. </li>
<li>Граватары с рейтингом X могут содержать откровенные сексуальные изображения или сцены экстремальной жестокости. </li>
</ul>
</p>

<p>Честно сказать, я слегка недопонял этот параметр. Когда я в своем профиле на <strong>gravatar </strong> добавил еще несколько изображений с рейтингом PG, R и X, то получил в результате ситуацию, что на сайте отображается либо самый жестокий аватар, либо отображается картинка по умолчанию для сайтов с рейтингом жестокости пониже. То есть я ожидал, что в зависимости от параметра r, переданного в url я увижу на сайте соответствующее рейтингу изображение, но увидел лишь картинку по умолчанию, что мне кажется
странным. Становится совершенно непонятным, зачем мне дана возможность загрузить несколько изображений, если в реальности работает только изображение с самым жестким рейтингом?
</p>
<p>Если ваш сайт использует протокол HTTPS>, то вы можете использовать URL https://secure.gravatar.com/ для загрузки аватарок через SSL. Все остальные параметры остаются прежними.</p>

<p>Gravatar, помимо аватарок, может отдавать еще и информацию о профиле пользователя. В нее входят почтовые адреса, телефоны, номера ICQ, skype, адреса персональных сайтов, и адреса профилей в ряде социальных сетей, twitter-е и т.д. Конечно, если пользователь заполнил эту информацию на сайте gravatar.com. </p>

<p>Получить доступ к этой информации очень просто - достаточно обратиться к URL вида: http://www.gravatar.com/HASH, где HASH - все тот же самый md5-хеш адреса электропочты пользователя. Например, вот ссылка на мой профиль: <a href="http://www.gravatar.com/b902d209d0efede9d9113a03c4ccb756">http://www.gravatar.com/b902d209d0efede9d9113a03c4ccb756</a>.</p>

<p>Попробуйте зайти по предложенному адресу и обратите внимание, что при обращении по этому адресу, ваш браузер получит редирект на url страницы профиля, например для моего профиля редирект будет вот на эту страницу http://ru.gravatar.com/vgrinin. Как видим, здесь просто добавился локализованный поддомен, и md5-хеш заменился на мой логин.</p>

<p>Обычно, сгенерированная страница профиля не годится для того, чтобы вставить информацию с нее в ваш сайт. Для этих целей создатели gravatar постарались и дали нам возможность получать информацию о профиле в нескольких удобных форматах: JSON, XML, PHP, VCF, QRCode.</p>

<p>JSON удобно использовать, если вы собираетесь вставлять информацию в страницу посредством JavaScript, хотя тут же возникнет вопрос о кросдоменном способе загрузки этой информации, ведь уровень безопасности браузера не позволит вам загрузить и выполнить скрипт с другого домена. </p>

<p>А поэтому следует обратиться в сторону остальных форматов загрузки и, соответственно, серверной обработке данных. Если вы программируете на PHP то удобнее всего будет воспользоваться PHP-форматом данных, который представляет собой строку объекта, сериализованного методом <em>serialize()</em>, так что обратное преобразование в объект мы можем провести методом <em>unserialize()</em>.</p>

<p>Чтобы не быть голословным, приведу пример PHP-кода, выводящего на экран ФИО пользователя и его аватарку.</p>

<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><div id="lc1"><span style="color: #19177C">$str</span> <span style="color: #666666">=</span> <span style="color: #008000">file_get_contents</span>(<span style="color: #BA2121">'http://www.gravatar.com/b902d209d0efede9d9113a03c4ccb756.php'</span>);
</div><div id="lc2"><span style="color: #19177C">$profile</span> <span style="color: #666666">=</span> <span style="color: #008000">unserialize</span>(<span style="color: #19177C">$str</span>);
</div><div id="lc3"><span style="color: #008000; font-weight: bold">if</span> (<span style="color: #008000">is_array</span>(<span style="color: #19177C">$profile</span>) <span style="color: #666666">&amp;&amp;</span> <span style="color: #008000">isset</span>(<span style="color: #19177C">$profile</span>[<span style="color: #BA2121">'entry'</span>]))
</div><div id="lc4">{
</div><div id="lc5"> <span style="color: #008000; font-weight: bold">echo</span> <span style="color: #19177C">$profile</span>[<span style="color: #BA2121">'entry'</span>][<span style="color: #666666">0</span>][<span style="color: #BA2121">'name'</span>][<span style="color: #BA2121">'formatted'</span>];
</div><div id="lc6">    <span style="color: #008000; font-weight: bold">echo</span> <span style="color: #BA2121">'&amp;lt;br/&amp;gt;&amp;lt;img src=&quot;'</span><span style="color: #666666">.</span><span style="color: #19177C">$profile</span>[<span style="color: #BA2121">'entry'</span>][<span style="color: #666666">0</span>][<span style="color: #BA2121">'thumbnailUrl'</span>]<span style="color: #666666">.</span><span style="color: #BA2121">'&quot;/&amp;gt;'</span>;
</div><div id="lc7">}
</div></pre></div>
<p style="padding: 0; margin: 2em 0 1em 0; font-size: 0.8em; color: #666;"><span style="padding: 0 1em; background-color: #f5f5f5;"> Colored with <a style="color: #333" href="http://dumpz.org">dumpz.org</a></span></p>

<p>Вот <a href="http://easy4web.ru/samples/gravatar/getprofile.php">здесь</a> вы можете протестировать этот скрипт. Обратите внимание, что желаемый формат информации профиля задается в виде "расширения" файла, запрашиваемого у сервиса. В нашем случае формат ".php". </p>

<p>Остальные форматы запрашиваем при помощи расширений: ".json", ".xml", ".vcf", ".qr". Саму структуру пакета данных удобнее всего просматривать в XML-формате, открыв в вашем браузере страницу http://www.gravatar.com/HASH.xml. </p>

<p>И еще хочу рассмотреть интересный формат - <strong>QRCode</strong>. Этот формат представляет собой <strong>2D-штрих-код</strong>, в котором зашифрован URL вашего профиля. Расшифровать его можно, например, на <a href="http://zxing.org/w/decode.jspx">этом сайте</a>. Если ввести в поле ввода строку http://ru.gravatar.com/b902d209d0efede9d9113a03c4ccb756.qr (это мой QR-код), то получим вот такой результат:</p>

<pre>
Raw text http://gravatar.com/vgrinin
Raw bytes 41 b6 87 47 47 03 a2 f2 f6 77 26 17 66 17 46 17 22 e6 36 f6 d2 f7 66 77 26 96 e6 96 e0 ec 11 ec 11 ec 11 ec
Barcode format QR_CODE
Parsed Result Type URI
Parsed Result http://gravatar.com/vgrinin
</pre>

<p>Как видно, в Parsed Result здесь содержится только мой URL, а я надеялся увидеть там несколько более подробную информацию.</p>

<p>Вот мы и рассмотрели все тонкости работы с сервисом gravatar. Спасибо его создателям, ведь сервис получился действительно нужным и популярным. Следует добавить, что все популярные CMS в том или ином виде содержат API для работы с этим сервисом, так что зачастую не надо утруждать себя нахождение MD5-хешей и прочими трудностями. </p>

<p>Надеюсь, статья была интересной и полезной.</p>
<!-- " ' --></td>
</tr>
</table>
 </table>
</center>]]></description>
<guid isPermaLink="false">1466114</guid>
<pubDate>Wed, 29 Jun 2011 11:34:12 MSD</pubDate>
</item>
<item>
<title>&#x412;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x430;? &#x42D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;!
</title>
<link>http://archives.maillist.ru/55140/1453450.html?rss=1</link>
<description><![CDATA[<style type="text/css"><!-- p { 
     padding-left: 10px; 
     padding-right: 10px; 
     font: 14px/20px Veradana, Arial, sans-serif; 
} 
 
span.drop { 
     font: bold 60px /0.83em tahoma, sans-serif; 
     color: #0019ff; 
     float: left; 
     margin-right: 5px; 
     margin-top: 5px; 
} 
 
 .list { 
     background-color: #f5f5f5; 
     border: 1px solid #ededed; 
     padding: 10px; 
     margin: 10px 40px 10px 40px; 
     font-family: courier, monospace; 
} 
 
h1{ 
     font-family: Verdana, Arial, Sans-Serif; 
     color:#fcb300; 
     font-size:28px; 
     font-weight:bold; 
     padding: 10px 0 0 10px; 
     text-align:left; 
} 
 --></style>
    
<table width="100%" summary="" cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" style="background-color: #ffffff; background-image: ;">
<tr valign="top" align="left">
<td bgcolor="#ffffff" style="padding: 5px; background-color: #ffffff; background-image: ;"><p>Сразу оговорюсь, какое отношение имеет цикл статей про Entity Framework к веб-программированию. В дальнейшем я собираюсь использовать полученную модель для создания веб-приложения на базе технологии ASP.NET MVC 3, которая очень хорошо сочетается с Entity Framework.
</p><p>
Прежде всего - вам нужно иметь установленную Visual Studio 2010 (кажется 2008 тоже подойдет) и установленный пакет <a target="_blank" href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=b41c728e-9b4f-4331-a1a8-537d16c6acdf&amp;displaylang=en">ADO.NET Entity Framework 4.1</a> найдите его по ссылке или в поиске на <em>microsoft.com</em>. Теперь нам становятся доступны все возможности ADO.NET Entity Framework. Замечу, что четвертая версия отличается от более ранних, так что, если у вас установлена
более ранняя версия, то не гарантирую, что у вас будет работать тот код, что я привел в статье.
</p><p>
Итак, создаем обычное консольное приложение. Присваиваем ему имя test1. Добавляем в проект модель данных. <em>Add -&gt; New Item... -&gt; ADO.NET Entity Data Model</em>, называем ее <em>MyEFModel.edmx</em>.
</p><p>
Среда разработки предлагает нам два варианта создания модели: генерация из базы данных и пустую модель. В этой статье мы собираемся рассмотреть принцип Model First, то есть начинать разработку мы будет с создания модели данных, из которой впоследствии будет сгенерирована схема данных (таблицы и связи в базе данных). А это значит, что мы выберем вариант создания пустой модели <em>Empty Model</em>. После этого перед нами откроется пустое поле дизайнера модели данных. Если дизайнер не открылся, то сделайте двойной
клик на модели <font face="courier new,courier,monospace">MyEFModel.edmx</font> в <em>Solution Explorer'е</em>.
</p><p>
Итак, мы хотим спроектировать модель данных для проверки пользовательских прав на те или иные операции. А значит в модели данных у нас будут присутствовать следующие сущности: <em>Пользователь (User), Группа (Group) и Право (Right)</em>. Каждый пользователь обязательно принадлежит какой либо группе, и при этом строго одной. Каждая группа содержит в себе несколько прав, или не содержит ни одного. Все просто - при регистрации нового пользователя создается одна сущность User, у которой есть свойство Group, привязывающее
пользователя к конкретной группе пользователей(например, администраторы, модераторы, авторы, читатели, посетители).  Группа в нашем случае это набор прав (таких как: &quot;блокирует пользователя&quot;, &quot;редактирует чужую статью&quot;, &quot;создает статью&quot;, &quot;читает статью&quot; и т.д.).
</p><p>
Перед тем как создавать сущности, давайте скажем дизайнеру модели, по каким правилам будут формироваться имена коллекций сущностей. Я вот о чем. Одновременно с сущностью в модели создается также контейнер этих сущностей, то есть по сути коллекция. Аналогия с таблицей в БД прямая: сущность - это строка в таблице, контейнер сущностей - сама таблица. Дизайнер дает имя контейнеру исходя из имени сущности (имя контейнера, впрочем, всегда можно поменять), и для сущности <em>User</em>, контейнер он может назвать <em>UserSet
</em>или <em>Users</em>. По мне так название <em>Users </em>гораздо приятнее. А потому для самой модели в свойствах мы выставим <em>Pluralize New Objects = True</em>.
</p><p>
Итак, создаем сущности(сущности создаются правым кликом на диаграмме модели данных и выбором контекстного меню <em>Add -&gt; Entity...</em>):
</p><p>
</p><ol>
<li>Entity Name = User
Entity; Set = Users.
Остальные свойства оставим без изменений. Заметим лишь, что по умолчанию дизайнер модели создает первичный ключ Id целочисленного типа, что для нас вполне приемлемо.
Добавляем в эту сущность свойства(Properties):
<ul><li>Login (Type = String, Max Length = 255);</li>
<li>Registered (Type = DateTime).</li></ul>
<br />Свойства добавляются в контекстном меню самой сущности (<em>Add -&gt; Scalar Property</em>).
</li>
<li>Entity Name = Group;
Entity Set = Groups.
Свойства:
Name (Type = String, Max Length = 255).</li>
<li>Entity Name = Right    Entity; Set = Rights.
Свойства:
Description (Type = String, Max Length = 255).</li></ol>
Итак, теперь у нас есть три сущности, пока еще не связанные друг с другом. Займемся этим вопросом.
Создаем связи (Add -&gt; Association):
<ol>
<li>Association Name = UserGroup;
Начало: Entity = User, Multiplicity = Many;
Конец: Entity = Group, Multiplicity = One.
Это соотношения &quot;Один ко многим&quot;, то есть каждый пользователь может состоять только в одной группе, но в каждой группе может быть много пользователей. (Если бы у сущности Group мы выбрали Multiplicity = Zero or One, то мы бы получили отношение &quot;Один ко многим&quot;, но дали бы при этом возможность иметь пользователей не принадлежащих ни одной группе, то есть у пользователя свойство Group было бы Nullable).
</li>
<li>Association Name = GroupRight;
Начало: Entity = Group, Multiplicity = Many;
Конец: Entity = Right, Multiplicity = Many.
Это соотношение &quot;Многие ко многим&quot;, то есть группа содержит в себе множество прав, при этом каждое право может принадлежать нескольким различным группам.
</li>
<p>Вот какая схема данных у нас появилась: <a id="datascheme1" name="datascheme1" class="anchor" href="http://easy4web.ru/?p=1169#datascheme1">рисунок<a href="http://easy4web.ru/wp-content/uploads/2011/05/datamodel.jpg"></a></a><a href="http://easy4web.ru/wp-content/uploads/2011/05/datamodel.jpg"><br /></a></p><p>
</p><p>
Обратите внимание, что после создания связей, в каждой из сущностей появились дополнительные навигационные свойства. Например, свойство <em>Group</em> сущности <em>User</em> дает нам возможность узнать группу, в которой состоит пользователь, а свойство <em>Rights</em> сущности <em>Group</em> дает нам возможность получить список всех прав группы. Таким образом, обратившись к <em>concreteUser.Group.Rights</em> мы получим список прав пользователя. Как видно из схемы данных, среда разработки создала также и встречные
(обратные) навигационные свойства <em>Right.Groups</em> и <em>Group.Users</em>.
</p><p>
Ну что же, модель данных готова. Но чтобы начать писать программный код, оперирующий с данными, нужно для начала создать саму базу данных. Используя Visual Studio2010 сделать это очень легко.
</p><p>
Правый щелчок мыши на диаграмме, затем в контекстном меню &quot;<em>Generate Database from Model...</em>&quot;. Здесь мы можем выбрать существующее подключение к БД или создать новое. Мы создадим новое подключение (кнопка <em>New Connection...</em>), здесь вы выбираете сервер БД, способ и параметры аутентификации, и имя базы данных (если хотите создать новую, то просто введите имя новой БД в поле <em>Select or enter a database name</em>), жмем OK. (Я создал базу <em>EFUSERS</em> на локальном компьютере). Мастер
спросит вас нужно ли создать БД, вы соглашайтесь. После этого мы снова вернемся в мастер генерации БД, убедитесь, что галочка &quot;<em>Save entity connection settings in App.config as</em>&quot; установлена и нажмите <em>Next</em>. После этого во вкладке DDL мастер отобразит вам DDL-скрипт схемы данных. Здесь вы нажмите <em>Finish</em>. 
</p><p>
После работы мастера мы получили следующее:
</p><ol><li><strong>скрипт схемы данных</strong> в файле MyEFModel.edmx.sql,
</li><li><strong>строка подключения</strong> MyEFModelContainer в файле App.config (откройте его и посмотрите в раздел сonnectionStrings)
</li><li>пока еще <strong>пустая база данных</strong> EFUSERS.
</li></ol><p>
Мастер всего лишь создает, но не выполняет DDL-скрипт и это правильно, потому что скрипт этот при выполнении уничтожает все данные в БД. Понятно, что при первом выполнении скрипта это нормально, ведь данных в БД еще нет. Но вот при последующих изменениях в модели данных и генерации новой схемы данных это может сыграть роковую роль и уничтожить все созданные ранее данные в базе. В последующих статьях мы еще рассмотрим способы внесения изменений в БД без потери существующих данных.
</p><p>
Теперь нам нужно выполнить DDL-крипт, чтобы создать все необходимые объекты в БД. Вы можете выполнить файл скрипта в Query Analizer, а можете сделать это прямо в Visual Studio, открыв скрипт и нажав кнопку Execute SQL в панели инструментов, или нажав комбинацию <em>Ctrl+Shift+E</em>. Студия запросит у вас параметры подключения к БД а затем выполнит скрипт. Открыв теперь базу в Enterprise Manager мы можем увидеть, что там создано 4 таблицы: <em>Users, Rights, Groups, GroupRight</em>. Первые три таблицы хранят
в себе сущности трех видов, а вот четвертую Junction-таблицу (<em>GroupRight</em>) Entity Framework создал для того чтобы хранить отношения &quot;Многие ко многим&quot; между сущностями <em>Group </em>и <em>Right</em>. Как видим, при помощи подхода <em>Model First</em> мы полностью ушли от этапа проектирования таблиц в БД, всю работу Entity Framework сделал за нас. Обратим также внимание, что в таблице <em>Users </em>появилась колонка <em>Group_Id</em> ссылающаяся на группу, в которую входит пользователь, колонка
эта <em>NOT NULL</em>, и это гарантирует что пользователь обязательно будет принадлежать той или иной группе. Ниже приведена схема БД, на которой отображены поля таблиц, первичные и внешние ключи.
</p><p>Схема хранения данных: <a id="tables" name="tables" class="anchor" href="http://easy4web.ru/?p=1169#tables">рисунок</a>. <br /></p><p>Можно заметить, что студия создала все необходимые внешние и первичные ключи для обеспечения целостности данных во всех таблицах. На схеме не изображены, но также присутствуют индексы для всех первичных и внешних ключей. Понятно, что студия не смогла предсказать, какие еще индексы могут вам понадобиться, так что впоследствии вы сможете самостоятельно добавить нужны индексы
для тех полей, по которым вы планируете часто проводить выборку данных.
</p><p>
Я не буду приводить здесь DDL-скрипт, сгенерированный студией, но он доступен для ознакомления по ссылке <a href="http://easy4web.ru/wp-content/uploads/2011/06/MyEFModel.edmx_.zip">MyEFModel.edmx</a>
</p><p>
Ну вот, вся предварительная работа сделана, модель данных нарисована, схема данных создана, пустые таблицы в БД присутствуют. Осталось теперь попробовать поработать со всем этим добром.
</p><p>
Чтобы обратиться к данным в БД, нужно создать экземпляр контейнера модели. Класс контейнера называется MyEFModelContainer, инстанцируем его:
</p><p>
</p><div class="highlight" style="background: none repeat scroll 0% 0% rgb(248, 248, 248);"><pre style="line-height: 125%;"><div id="lc1">MyEFModelContainer cnt = 
</div><div id="lc2">  <span style="color: rgb(0, 128, 0); font-weight: bold;">new</span> <span style="color: rgb(0, 0, 255);">MyEFModelContainer</span>(<span style="color: rgb(186, 33, 33);">&quot;name=MyEFModelContainer&quot;</span>);
</div></pre></div>
<p>&nbsp;В качестве аргумента конструктора мы задаем имя строки подключения к БД. Эта строка подключения представляет собой нечто большее, чем обычная ConnectionString для подключения к базе данных, потому что в нашем случае используется провайдер System.Data.EntityClient, которому для инициализации требуется гораздо больше параметров. Строка подключения была создана мастером ранее и хранится в файле App.config, строка подключения выглядит так:
</p><p>
</p><pre>provider=System.Data.SqlClient;
provider connection string=&amp;quot;data source=.;initial catalog=EFUSERS;
integrated security=True;multipleactiveresultsets=True;App=EntityFramework&amp;quot;</pre>
<p>Посмотрите внимательно, строка подключения имеет в себе три обязательных параметра: <em>metadata, provider и provider connection string</em>. Первый параметр задает ссылки на файлы <em>CSDL, SSDL и MSL</em> моделей. Все эти три файла хранятся в папке edmxResourcesToEmbed(найдите ее в дереве каталогов проекта) и представляют собой XML-файлы, описывающие соответственно: CSDL - концептуальную(объектную) модель в терминах бизнес-уровня, SSDL - схема хранения (реляционная схема), MSL - схема сопоставления (то
есть связи между элементами CSDL и SSDL). Собственно все эти XML-файлы объединены в один с расширением EDMX.
</p><p>
Параметры <em>provider </em>и<em> provider connection string</em> задают как раз привычную нам строку подключения к БД.
</p><p>
Конструктор класса <em>MyEFModelContainer </em>можно вызвать также совсем без параметров, тогда по умолчанию строка подключения будет взята из <em>App.config</em> и станет равна той строке подключения, для которой собственно генерировался изначально DDL-скрипт.
</p><p>
В качестве аргумента конструктора класса <em>MyEFModelContainer </em>можно подать также экземпляр класса <em>EntityConnection</em>, который есть по сути объектная обертка вокруг строки подключения, мы не будет усложнять код, потому что конструктор класса <em>MyEFModelContainer </em>все равно сделает эту работу за нас.
</p><p>
Итак, теперь у нас есть контейнер данных, который помимо огромного количества прочих полезностей, содержит в себе три коллекции: <em>Users, Groups, Rights</em> - это те самые коллекции, ради которых собственно все и затевалось. Операции, производимые нами над этими коллекциями, автоматически (ну или почти автоматически) отображаются в базу данных, добавляя, удаляя или изменяя строки в соответствующих таблицах. Попытка чтения из коллекции приведет к выполнению SELECT-запроса к соответствующей таблице.
</p><p>
Пока наши таблицы пусты попробуем добавить в них некоторые данные. Пусть мы хотим, чтобы существовали два пользователя: chitatel и pushkin. Первый по статусу положено только чтение статей, второму - и чтение и запись. Понятно, что никаких статей у нас пока нет, важно только само разграничение прав на операции. При этом chitatel принадлежит группе &quot;Читатели&quot;, а pushkin - группе &quot;Писатели&quot;. Таким образом нам нужно создать два права: &quot;Читать статьи&quot; и &quot;Редактировать статьи&quot;;
две группы: &quot;Читатели&quot; и &quot;Писатели&quot;; двух пользователей: chitatel и pushkin. А также - создать между ними корректные связи. Приведу сразу кусок кода, который надо выполнить единожды для того, чтобы создать все необходимые записи в таблицах.
</p><p>
</p><div class="highlight" style="background: none repeat scroll 0% 0% rgb(248, 248, 248);"><pre style="line-height: 125%;"><div id="lc1"><span style="color: rgb(64, 128, 128); font-style: italic;">// Создаем объекты прав</span>
</div><div id="lc2">Right canRead = <span style="color: rgb(0, 128, 0); font-weight: bold;">new</span> Right()
</div><div id="lc3">{
</div><div id="lc4">  Description=<span style="color: rgb(186, 33, 33);">&quot;Читать статьи&quot;</span>,
</div><div id="lc5">};
</div><div id="lc6">Right canWrite = <span style="color: rgb(0, 128, 0); font-weight: bold;">new</span> Right()
</div><div id="lc7">{
</div><div id="lc8">  Description=<span style="color: rgb(186, 33, 33);">&quot;Редактировать статьи&quot;</span>,
</div><div id="lc9">};
</div><div id="lc10"><span style="color: rgb(64, 128, 128); font-style: italic;">// Создаем объекты групп</span>
</div><div id="lc11">Group groupReaders = <span style="color: rgb(0, 128, 0); font-weight: bold;">new</span> Group()
</div><div id="lc12">{
</div><div id="lc13">  Name = <span style="color: rgb(186, 33, 33);">&quot;Читатели&quot;</span>
</div><div id="lc14">};
</div><div id="lc15">Group groupWriters = <span style="color: rgb(0, 128, 0); font-weight: bold;">new</span> Group()
</div><div id="lc16">{
</div><div id="lc17">  Name = <span style="color: rgb(186, 33, 33);">&quot;Писатели&quot;</span>
</div><div id="lc18">};
</div><div id="lc19"><span style="color: rgb(64, 128, 128); font-style: italic;">// Присваиваем группам соответствующие права</span>
</div><div id="lc20">groupReaders.Rights.Add(canRead);  <span style="color: rgb(64, 128, 128); font-style: italic;">// читатели могут только читать</span>
</div><div id="lc21">groupWriters.Rights.Add(canRead);  <span style="color: rgb(64, 128, 128); font-style: italic;">// писатели могут и читать</span>
</div><div id="lc22">groupWriters.Rights.Add(canWrite); <span style="color: rgb(64, 128, 128); font-style: italic;">// и писать</span>
</div><div id="lc23">
</div><div id="lc24"><span style="color: rgb(64, 128, 128); font-style: italic;">// Создаем объекты пользователей и заносим их в соответствующую группу</span>
</div><div id="lc25">User userChitatel = <span style="color: rgb(0, 128, 0); font-weight: bold;">new</span> User()
</div><div id="lc26">{
</div><div id="lc27">  Login = <span style="color: rgb(186, 33, 33);">&quot;chitatel&quot;</span>,
</div><div id="lc28">  Registered = DateTime.Now,
</div><div id="lc29">  Group = groupReaders
</div><div id="lc30">};
</div><div id="lc31">
</div><div id="lc32">User userPushkin = <span style="color: rgb(0, 128, 0); font-weight: bold;">new</span> User()
</div><div id="lc33">{
</div><div id="lc34">  Login = <span style="color: rgb(186, 33, 33);">&quot;pushkin&quot;</span>,
</div><div id="lc35">  Registered = DateTime.Now,
</div><div id="lc36">  Group=groupWriters
</div><div id="lc37">};
</div><div id="lc38">
</div><div id="lc39"><span style="color: rgb(64, 128, 128); font-style: italic;">// Теперь все эти существующие исключительно в памяти объекты</span>
</div><div id="lc40"><span style="color: rgb(64, 128, 128); font-style: italic;">// добавляем в соответствующие коллекции контейнера</span>
</div><div id="lc41"><span style="color: rgb(0, 128, 0); font-weight: bold;">using</span> (MyEFModelContainer cnt = 
</div><div id="lc42">  <span style="color: rgb(0, 128, 0); font-weight: bold;">new</span> <span style="color: rgb(0, 0, 255);">MyEFModelContainer</span>(<span style="color: rgb(186, 33, 33);">&quot;name=MyEFModelContainer&quot;</span>))
</div><div id="lc43">{
</div><div id="lc44">  cnt.Rights.AddObject(canRead);
</div><div id="lc45">  cnt.Rights.AddObject(canWrite);
</div><div id="lc46">  cnt.Groups.AddObject(groupReaders);
</div><div id="lc47">  cnt.Groups.AddObject(groupWriters);
</div><div id="lc48">  cnt.Users.AddObject(userChitatel);
</div><div id="lc49">  cnt.Users.AddObject(userPushkin);
</div><div id="lc50">  <span style="color: rgb(64, 128, 128); font-style: italic;">// И финальный аккорд - сохраняем все изменения в БД</span>
</div><div id="lc51">  cnt.SaveChanges();
</div><div id="lc52">}
</div></pre></div>
<p style="padding: 0pt; margin: 2em 0pt 1em; font-size: 0.8em; color: rgb(102, 102, 102);"><span style="padding: 0pt 1em; background-color: rgb(245, 245, 245);"> Colored with <a style="color: rgb(51, 51, 51);" href="http://dumpz.org">dumpz.org</a></span></p>
<p>&nbsp;После выполнения приведенного кода мы получим вот такие данные в таблицах: <a id="tablesdata" name="tablesdata" class="anchor" href="http://easy4web.ru/?p=1169#tablesdata">рисунок</a>.</p><p>
Рассмотрим теперь алгоритм выборки данных из контейнера. Я для этих целей буду использовать язык встроенных запросов LINQ.Предположим, что некий пользователь вошел в систему, и нам нужно определить, имеет ли он право редактировать статьи. То есть мы должны по имени пользователя получить его группу и посмотреть, имеет ли эта группа соответствующее право.
</p><p>
Для этого мы выполним следующий код:
</p><div style="background: none repeat scroll 0% 0% rgb(248, 248, 248);" class="highlight"><pre style="line-height: 125%;"><div id="lc1">            <span style="color: rgb(0, 128, 0); font-weight: bold;">using</span> (MyEFModelContainer cnt = 
</div><div id="lc2">                     <span style="color: rgb(0, 128, 0); font-weight: bold;">new</span> <span style="color: rgb(0, 0, 255);">MyEFModelContainer</span>(<span style="color: rgb(186, 33, 33);">&quot;name=MyEFModelContainer&quot;</span>))
</div><div id="lc3">            {
</div><div id="lc4">                var check = from u <span style="color: rgb(0, 128, 0); font-weight: bold;">in</span> cnt.Users
</div><div id="lc5">                            where u.Login == <span style="color: rgb(186, 33, 33);">&quot;pushkin&quot;</span> &amp;&amp; 
</div><div id="lc6">               u.Group.Rights.Any(f =&amp;gt; f.Description == <span style="color: rgb(186, 33, 33);">&quot;Редактировать статьи&quot;</span>)
</div><div id="lc7">                            select u;
</div><div id="lc8">                Console.WriteLine(check.Count());
</div><div id="lc9">            }
</div></pre></div><p>&nbsp;Дословно, LINQ-запрос выбирает из БД всех пользователей, имеющих заданный логин(то есть единственного пользователя), и в правах группы в поле Description имеющих содержимое &quot;Редактировать статьи&quot;. Если такой пользователь существует, то check.Count() == 1, а значит пользователь имеет требуемое право.
</p><p>
Текст SQL-запроса, выполненного в БД, выглядит так:
</p><div style="background: none repeat scroll 0% 0% rgb(248, 248, 248);" class="highlight"><pre style="line-height: 125%;"><div id="lc1"><span style="color: rgb(0, 128, 0); font-weight: bold;">SELECT</span> 
</div><div id="lc2">[GroupBy1].[A1] <span style="color: rgb(0, 128, 0); font-weight: bold;">AS</span> [C1]
</div><div id="lc3"><span style="color: rgb(0, 128, 0); font-weight: bold;">FROM</span> ( <span style="color: rgb(0, 128, 0); font-weight: bold;">SELECT</span> 
</div><div id="lc4"> <span style="color: rgb(0, 128, 0); font-weight: bold;">COUNT</span>(<span style="color: rgb(102, 102, 102);">1</span>) <span style="color: rgb(0, 128, 0); font-weight: bold;">AS</span> [A1]
</div><div id="lc5"> <span style="color: rgb(0, 128, 0); font-weight: bold;">FROM</span> [dbo].[Users] <span style="color: rgb(0, 128, 0); font-weight: bold;">AS</span> [Extent1]
</div><div id="lc6"> <span style="color: rgb(0, 128, 0); font-weight: bold;">WHERE</span> (N<span style="color: rgb(186, 33, 33);">'pushkin'</span> <span style="color: rgb(102, 102, 102);">=</span> [Extent1].[Login]) <span style="color: rgb(0, 128, 0); font-weight: bold;">AND</span> ( <span style="color: rgb(0, 128, 0); font-weight: bold;">EXISTS</span> (<span style="color: rgb(0, 128, 0); font-weight: bold;">SELECT</span> 
</div><div id="lc7">  <span style="color: rgb(102, 102, 102);">1</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">AS</span> [C1]
</div><div id="lc8">  <span style="color: rgb(0, 128, 0); font-weight: bold;">FROM</span>  [dbo].[GroupRight] <span style="color: rgb(0, 128, 0); font-weight: bold;">AS</span> [Extent2]
</div><div id="lc9">  <span style="color: rgb(0, 128, 0); font-weight: bold;">INNER</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">JOIN</span> [dbo].[Rights] <span style="color: rgb(0, 128, 0); font-weight: bold;">AS</span> [Extent3] <span style="color: rgb(0, 128, 0); font-weight: bold;">ON</span> [Extent2].[Rights_Id] <span style="color: rgb(102, 102, 102);">=</span> [Extent3].[Id]
</div><div id="lc10">  <span style="color: rgb(0, 128, 0); font-weight: bold;">WHERE</span> (N<span style="color: rgb(186, 33, 33);">'Редактировать статьи'</span> <span style="color: rgb(102, 102, 102);">=</span> [Extent3].[Description]) <span style="color: rgb(0, 128, 0); font-weight: bold;">AND</span> ([Extent1].[Group_Id] <span style="color: rgb(102, 102, 102);">=</span> [Extent2].[Groups_Id])
</div><div id="lc11"> ))
</div><div id="lc12">)  <span style="color: rgb(0, 128, 0); font-weight: bold;">AS</span> [GroupBy1]
</div></pre></div>
<p style="padding: 0pt; margin: 2em 0pt 1em; font-size: 0.8em; color: rgb(102, 102, 102);"><span style="padding: 0pt 1em; background-color: rgb(245, 245, 245);"> Colored with <a href="http://dumpz.org" style="color: rgb(51, 51, 51);">dumpz.org</a></span></p>
<p>&nbsp;Здесь мы видим безобразный SELECT FROM SELECT отягощенный EXISTS-ом и INNER JOIN-ом. На мой взгляд, запрос далеко не оптимален. Немного упростить запрос, убрав из него INNER JOIN можно, если искать права не по названию (&quot;Редактировать статьи&quot;), что в любом случае являет плохим тоном, потому что зависит от способа написания названия права, а искать по Id права, ведь согласитесь сопоставление ID и DESCRIPTION в нашей базе всегда будет сохраняться. Таким образом, упрощаем LINQ-запрос:
</p><div style="background: none repeat scroll 0% 0% rgb(248, 248, 248);" class="highlight"><pre style="line-height: 125%;"><div id="lc1">var check = from u <span style="color: rgb(0, 128, 0); font-weight: bold;">in</span> cnt.Users
</div><div id="lc2">  where u.Login == <span style="color: rgb(186, 33, 33);">&quot;pushkin&quot;</span> &amp;&amp; 
</div><div id="lc3">    u.Group.Rights.Any(f =&gt; f.Id == <span style="color: rgb(102, 102, 102);">2</span>)
</div><div id="lc4">  select u;
</div></pre></div><p>&nbsp;И получаем слегка укороченный SQL-запрос:
</p><div style="background: none repeat scroll 0% 0% rgb(248, 248, 248);" class="highlight"><pre style="line-height: 125%;"><div id="lc1"><span style="color: rgb(0, 128, 0); font-weight: bold;">SELECT</span> 
</div><div id="lc2">[GroupBy1].[A1] <span style="color: rgb(0, 128, 0); font-weight: bold;">AS</span> [C1]
</div><div id="lc3"><span style="color: rgb(0, 128, 0); font-weight: bold;">FROM</span> ( <span style="color: rgb(0, 128, 0); font-weight: bold;">SELECT</span> 
</div><div id="lc4"> <span style="color: rgb(0, 128, 0); font-weight: bold;">COUNT</span>(<span style="color: rgb(102, 102, 102);">1</span>) <span style="color: rgb(0, 128, 0); font-weight: bold;">AS</span> [A1]
</div><div id="lc5"> <span style="color: rgb(0, 128, 0); font-weight: bold;">FROM</span> [dbo].[Users] <span style="color: rgb(0, 128, 0); font-weight: bold;">AS</span> [Extent1]
</div><div id="lc6"> <span style="color: rgb(0, 128, 0); font-weight: bold;">WHERE</span> (N<span style="color: rgb(186, 33, 33);">'pushkin'</span> <span style="color: rgb(102, 102, 102);">=</span> [Extent1].[Login]) <span style="color: rgb(0, 128, 0); font-weight: bold;">AND</span> ( <span style="color: rgb(0, 128, 0); font-weight: bold;">EXISTS</span> (<span style="color: rgb(0, 128, 0); font-weight: bold;">SELECT</span> 
</div><div id="lc7">  <span style="color: rgb(102, 102, 102);">1</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">AS</span> [C1]
</div><div id="lc8">  <span style="color: rgb(0, 128, 0); font-weight: bold;">FROM</span> [dbo].[GroupRight] <span style="color: rgb(0, 128, 0); font-weight: bold;">AS</span> [Extent2]
</div><div id="lc9">  <span style="color: rgb(0, 128, 0); font-weight: bold;">WHERE</span> (<span style="color: rgb(102, 102, 102);">2</span> <span style="color: rgb(102, 102, 102);">=</span> [Extent2].[Rights_Id]) <span style="color: rgb(0, 128, 0); font-weight: bold;">AND</span> ([Extent1].[Group_Id] <span style="color: rgb(102, 102, 102);">=</span> [Extent2].[Groups_Id])
</div><div id="lc10"> ))
</div><div id="lc11">)  <span style="color: rgb(0, 128, 0); font-weight: bold;">AS</span> [GroupBy1]
</div></pre></div>
<p style="padding: 0pt; margin: 2em 0pt 1em; font-size: 0.8em; color: rgb(102, 102, 102);"><span style="padding: 0pt 1em; background-color: rgb(245, 245, 245);"> Colored with <a href="http://dumpz.org" style="color: rgb(51, 51, 51);">dumpz.org</a></span></p>
<p>&nbsp;Я думаю, что на начальном этапе создания проекта, когда таблицы будут еще не слишком большими, подойдет и этот запрос, в дальнейшем же мы просто будем выносить все часто используемые не слишком оптимальные запросы в отдельные оптимизированные хранимые функции и процедуры. К счастью в Entity Framework 4 заложена возможность вызова хранимых процедур и функций, и не просто их вызова, а даже использования их в LINQ-запросах, что согласитесь очень хорошо.
</p><p>
Итак мы научились создавать модель данных, генерировать из нее схему данных, создавать сущности и делать из них выборку.
</p><p>
В следующей статье я планирую коснуться изменения (UPDATE) сущностей и изменения схемы данных (ALTER), создания и использования хранимых функций и процедур. 
</p><p>
Проект можно скачать здесь <a href="http://easy4web.ru/wp-content/uploads/2011/06/test1.zip">test1</a>
</p></ol>
<!-- " ' --></td>
</tr>
</table>
 </table>
</center>]]></description>
<guid isPermaLink="false">1453450</guid>
<pubDate>Tue, 07 Jun 2011 10:47:03 MSD</pubDate>
</item>
<item>
<title>&#x412;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x430;? &#x42D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;! Ru-Center &#x43E;&#x442;&#x434;&#x430;&#x435;&#x442; &#x434;&#x435;&#x43D;&#x44C;&#x433;&#x438;, &#x430; &#x442;&#x432;&#x438;&#x442;&#x442;&#x435;&#x440; &#x43E;&#x442;&#x43A;&#x440;&#x44B;&#x432;&#x430;&#x435;&#x442; &#x432;&#x438;&#x434;&#x435;&#x43E;&#x445;&#x43E;&#x441;&#x442;&#x438;&#x43D;&#x433;
</title>
<link>http://archives.maillist.ru/55140/1450641.html?rss=1</link>
<description><![CDATA[<style type="text/css"><!-- p { 
     padding-left: 10px; 
     padding-right: 10px; 
     font: 14px/20px Veradana, Arial, sans-serif; 
} 
 
span.drop { 
     font: bold 60px /0.83em tahoma, sans-serif; 
     color: #0019ff; 
     float: left; 
     margin-right: 5px; 
     margin-top: 5px; 
} 
 
 .list { 
     background-color: #f5f5f5; 
     border: 1px solid #ededed; 
     padding: 10px; 
     margin: 10px 40px 10px 40px; 
     font-family: courier, monospace; 
} 
 
h1{ 
     font-family: Verdana, Arial, Sans-Serif; 
     color:#fcb300; 
     font-size:28px; 
     font-weight:bold; 
     padding: 10px 0 0 10px; 
     text-align:left; 
} 
 --></style>
    
<table width="100%" summary="" cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" style="background-color: #ffffff; background-image: ;">
<tr valign="top" align="left">
<td bgcolor="#ffffff" style="padding: 5px; background-color: #ffffff; background-image: ;"><h1>RU-Center отдает деньги за купленные в зоне .РФ домены <br /></h1><p>Покупка компании Ru-Center должна завершиться к концу 2011 года, когда АНО &quot;РСИЦ&quot; будет ликвидировано, а все клиенты вместо со своими доменными именами перейдут под управление ЗАО &quot;Региональный сетевой информационный центр&quot;. Напомню, что группа Hosting Community, покупает Ru-Center, а точнее две из трех, входящих в Ru-Center компании - ЗАО &quot;РСИЦ&quot; и ООО &quot;НИК Медиа&quot;.<br /><br />Компанию АНО &quot;РСИЦ&quot;
купить невозможно, потому что она является некоммерческой организацией, а значит купить ее невозможно. На данный момент осталось перевести из АНО в ЗАО более 200 тысяч доменов. Перевод клиентов под крыло группы Hosting Community будет происходить постепенно - при попытке продлить доменное имя клиенту будет предложено перевести домен в ЗАО &quot;РСИЦ&quot; либо уйти к другому регистратору.<br /><br />Федеральная Антимонопольная Служба продолжает разбираться с сомнительным проведением доменных аукционов в зоне
.РФ, пытаясь найти в нем признаки картельного сговора. Если подозрения подтвердятся, то РСИЦ будет оштрафован. Но что делать тем, кто купил втридорога домен в зоне .РФ и планирует от него отказаться.<br /><br />Александр Панов (управляющий партнер группы Hosting Community) утверждает, что такие люди могут получить назад свои деньги, вернув домен регистратору. Деньги им будет возвращать непосредственно Ru-Center, так как HC считает, что не обязан отвечать за обязательства взятые до них (Что на мой взгляд весьма
странно, ведь обычно компания покупается вместе со своими долгами и обязательствами. Или я не прав???)<br /><br />Несостоявшиеся покупатели проигравшие аукцион, не могут претендовать на домены, выигравшие владельцы которых не планируют отказываться от своих доменов.<br />Hosting Community не боится санкций со стороны ФАС за превышение доли занимаемого рынка после поглощения Ru-Center, так как считает хостинг телематической услугой, а значит делит этот рынок вместе с крупными операторами сотовой связи. Что ж,
время покажет...</p><p>Приглашаем <a href="http://easy4web.ru/?p=1188" title="обсудить эту новость">обсудить эту новость</a>.<br /></p><h1>Птичка разжирнела<br /></h1><p>Лавры Youtube - крупного видеохостера, не дают покоя сервису микроблогов Twitter, и вот уже и они построили у себя фото и видеохостинг.<br /><br />И если открытие фотохостинга был ожидаемым событием, то возможность хранить видео стала новостью. Так что очень скоро это существенно скажется на бизнесе таких конкурентов, как Twitpic и Yfrog, ведь
вполне можно ожидать конкретных недружественных действий Twitter против сервисов сторонних компаний.<br /><br />Совсем скоро пользователи твиттера, работающие со своих мобильных устройств, получат обновленные версии приложений, поддерживающие новые функции сервиса.<br /><br />Ну что же, все хотят зарабатывать много денег, а потому в процессе коммерческого развития твиттер все больше отдаляется от своих начальных целей - создание простого сервиса микроблогов. Маленькая чирикающая птичка превращается в жирное
откормленное чудовище, а уютный твиттер - в огромную корпорацию.</p><p>&nbsp;Приглашаем <a href="http://easy4web.ru/?p=1190" title="обсудить эту новость">обсудить эту новость</a><br /></p><p>&nbsp;</p>
<!-- " ' --></td>
</tr>
</table>
 </table>
</center>]]></description>
<guid isPermaLink="false">1450641</guid>
<pubDate>Thu, 02 Jun 2011 11:31:18 MSD</pubDate>
</item>
<item>
<title>&#x412;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x430;? &#x42D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;! &#x41F;&#x443;&#x43B; &#x434;&#x430;&#x43D;&#x43D;&#x44B;&#x445;
</title>
<link>http://archives.maillist.ru/55140/1449374.html?rss=1</link>
<description><![CDATA[<style type="text/css"><!-- p { 
     padding-left: 10px; 
     padding-right: 10px; 
     font: 14px/20px Veradana, Arial, sans-serif; 
} 
 
span.drop { 
     font: bold 60px /0.83em tahoma, sans-serif; 
     color: #0019ff; 
     float: left; 
     margin-right: 5px; 
     margin-top: 5px; 
} 
 
 .list { 
     background-color: #f5f5f5; 
     border: 1px solid #ededed; 
     padding: 10px; 
     margin: 10px 40px 10px 40px; 
     font-family: courier, monospace; 
} 
 
h1{ 
     font-family: Verdana, Arial, Sans-Serif; 
     color:#fcb300; 
     font-size:28px; 
     font-weight:bold; 
     padding: 10px 0 0 10px; 
     text-align:left; 
} 
 --></style>
    
<table width="100%" summary="" cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" style="background-color: #ffffff; background-image: ;">
<tr valign="top" align="left">
<td bgcolor="#ffffff" style="padding: 5px; background-color: #ffffff; background-image: ;"><p><span style="color:#528BC5; font-size:16pt;">Новости...</span> Ведущие разработчики браузеров планируют отказаться от привычной всем пользователям адресной строки. Что будет вместо нее? <a href="http://easy4web.ru/?p=1166">Приглашаем к обсуждению</a> на нашем сайте.</p>
<p></p>
<h1>Пул данных</h1>

<p>Всем привет. Сегодня мы поговорим о пуле данных. Под словосочетанием &quot;пул данных&quot; частенько понимаются принципиально разные вещи. Например, система, которая имитирует пользовательский ввод данных и используется для автоматического тестирования какой-либо другой системы. Я же буду подразумевать под пулом данных некоторую программно-алгоритмическую структуру, предназначенную для хранения данных и работы с ними. 

</p><p>Итак, зачем вообще нужен пул данных? Основной принцип разработки софта - модульность. То есть мы стремимся к тому, чтобы минимизировать зависимости между классами, чтобы наша программа была не монолитным куском кода, а набором некоторых подпрограмм, которые можно комбинировать друг с другом, добиваясь гибкости и расширяемости системы. Понятное дело, такой подход - результат эволюции. И его преимущества сложно переоценить. Хотя бы тот факт, что в монолитной программе исправление какого-нибудь участка кода
может запросто привести к веерным изменениям по всему монолиту, в то время, как в хорошо продуманной модульной структуре любые изменения останутся локальными, главное только сохранить формат и логику входных и выходных параметров.
</p><p>
Проблема заключается в следующем - большую модульную систему могут разрабатывать не то, что разные отделы внутри одной компании, а и вообще разные компании. При этом, каждый модуль будет замечательно работать, но все эти модули будут работать с данными в разных форматах. Я сейчас объясню, что я имею ввиду. Считается, что системе достаточно  быть хорошо задокументированной, чтобы избежать этих проблем. Фактически, происходит следующее.</p><p>Допустим, есть набор некоторых данных и несколько хорошо задокументированных
классов. 
</p>
<pre><div style="background: none repeat scroll 0% 0% rgb(248, 248, 248);" class="highlight"><pre style="line-height: 125%;"><div id="lc1"><span style="color: rgb(25, 23, 124);">$data</span> <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">array</span>();
</div><div id="lc2">
</div><div id="lc3"><span style="color: rgb(25, 23, 124);">$data</span>[<span style="color: rgb(186, 33, 33);">'a'</span>] <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(102, 102, 102);">1</span>;
</div><div id="lc4"><span style="color: rgb(25, 23, 124);">$data</span>[<span style="color: rgb(186, 33, 33);">'b'</span>] <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(102, 102, 102);">2</span>;
</div><div id="lc5"><span style="color: rgb(25, 23, 124);">$data</span>[<span style="color: rgb(186, 33, 33);">'c'</span>] <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(102, 102, 102);">3</span>;
</div><div id="lc6"><span style="color: rgb(25, 23, 124);">$data</span>[<span style="color: rgb(186, 33, 33);">'d'</span>] <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(102, 102, 102);">4</span>;
</div><div id="lc7">
</div><div id="lc8"><span style="color: rgb(0, 128, 0); font-weight: bold;">class</span> <span style="color: rgb(0, 0, 255); font-weight: bold;">A</span>
</div><div id="lc9">{
</div><div id="lc10">    <span style="color: rgb(0, 128, 0); font-weight: bold;">private</span> <span style="color: rgb(25, 23, 124);">$a</span> <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(102, 102, 102);">0</span>;
</div><div id="lc11">    <span style="color: rgb(0, 128, 0); font-weight: bold;">private</span> <span style="color: rgb(25, 23, 124);">$b</span> <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(102, 102, 102);">0</span>;
</div><div id="lc12">
</div><div id="lc13">    <span style="color: rgb(0, 128, 0); font-weight: bold;">public</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">function</span> <span style="color: rgb(0, 0, 255);">__construct</span>(<span style="color: rgb(25, 23, 124);">$a</span>, <span style="color: rgb(25, 23, 124);">$b</span>)
</div><div id="lc14">    {
</div><div id="lc15">        <span style="color: rgb(25, 23, 124);">$this</span><span style="color: rgb(102, 102, 102);">-&gt;</span><span style="color: rgb(125, 144, 41);">a</span> <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(25, 23, 124);">$a</span>;
</div><div id="lc16">        <span style="color: rgb(25, 23, 124);">$this</span><span style="color: rgb(102, 102, 102);">-&gt;</span><span style="color: rgb(125, 144, 41);">b</span> <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(25, 23, 124);">$b</span>;
</div><div id="lc17">    }
</div><div id="lc18">
</div><div id="lc19">    <span style="color: rgb(0, 128, 0); font-weight: bold;">public</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">function</span> <span style="color: rgb(0, 0, 255);">process_data</span>()
</div><div id="lc20">    {
</div><div id="lc21">        <span style="color: rgb(64, 128, 128); font-style: italic;">//.......</span>
</div><div id="lc22">    }
</div><div id="lc23">
</div><div id="lc24">    <span style="color: rgb(0, 128, 0); font-weight: bold;">public</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">function</span> <span style="color: rgb(0, 0, 255);">return_data</span>()
</div><div id="lc25">    {
</div><div id="lc26">        <span style="color: rgb(25, 23, 124);">$arr</span> <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">array</span>();
</div><div id="lc27">
</div><div id="lc28">        <span style="color: rgb(25, 23, 124);">$arr</span>[<span style="color: rgb(186, 33, 33);">'a'</span>] <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(25, 23, 124);">$this</span><span style="color: rgb(102, 102, 102);">-&gt;</span><span style="color: rgb(125, 144, 41);">a</span>;
</div><div id="lc29">        <span style="color: rgb(25, 23, 124);">$arr</span>[<span style="color: rgb(186, 33, 33);">'b'</span>] <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(25, 23, 124);">$this</span><span style="color: rgb(102, 102, 102);">-&gt;</span><span style="color: rgb(125, 144, 41);">b</span>;
</div><div id="lc30">
</div><div id="lc31">        <span style="color: rgb(0, 128, 0); font-weight: bold;">return</span> <span style="color: rgb(25, 23, 124);">$arr</span>;
</div><div id="lc32">    }
</div><div id="lc33">}
</div><div id="lc34">
</div><div id="lc35"><span style="color: rgb(0, 128, 0); font-weight: bold;">class</span> <span style="color: rgb(0, 0, 255); font-weight: bold;">B</span>
</div><div id="lc36">{
</div><div id="lc37">    <span style="color: rgb(0, 128, 0); font-weight: bold;">private</span> <span style="color: rgb(25, 23, 124);">$arr</span> <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">array</span>();
</div><div id="lc38">
</div><div id="lc39">    <span style="color: rgb(0, 128, 0); font-weight: bold;">public</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">function</span> <span style="color: rgb(0, 0, 255);">__construct</span>(<span style="color: rgb(25, 23, 124);">$a</span>, <span style="color: rgb(25, 23, 124);">$b</span>)
</div><div id="lc40">    {
</div><div id="lc41">        <span style="color: rgb(25, 23, 124);">$this</span><span style="color: rgb(102, 102, 102);">-&gt;</span><span style="color: rgb(125, 144, 41);">arr</span>[<span style="color: rgb(186, 33, 33);">'a'</span>] <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(25, 23, 124);">$a</span>;
</div><div id="lc42">        <span style="color: rgb(25, 23, 124);">$this</span><span style="color: rgb(102, 102, 102);">-&gt;</span><span style="color: rgb(125, 144, 41);">arr</span>[<span style="color: rgb(186, 33, 33);">'b'</span>] <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(25, 23, 124);">$b</span>;
</div><div id="lc43">    }
</div><div id="lc44">
</div><div id="lc45">    <span style="color: rgb(0, 128, 0); font-weight: bold;">public</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">function</span> <span style="color: rgb(0, 0, 255);">process_data</span>()
</div><div id="lc46">    {
</div><div id="lc47">        <span style="color: rgb(64, 128, 128); font-style: italic;">//.......</span>
</div><div id="lc48">    }
</div><div id="lc49">
</div><div id="lc50">    <span style="color: rgb(0, 128, 0); font-weight: bold;">public</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">function</span> <span style="color: rgb(0, 0, 255);">return_a</span>()
</div><div id="lc51">    {
</div><div id="lc52">        <span style="color: rgb(0, 128, 0); font-weight: bold;">return</span> <span style="color: rgb(25, 23, 124);">$this</span><span style="color: rgb(102, 102, 102);">-&gt;</span><span style="color: rgb(125, 144, 41);">arr</span>[<span style="color: rgb(186, 33, 33);">'a'</span>];
</div><div id="lc53">    }
</div><div id="lc54">
</div><div id="lc55">    <span style="color: rgb(0, 128, 0); font-weight: bold;">public</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">function</span> <span style="color: rgb(0, 0, 255);">return_b</span>()
</div><div id="lc56">    {
</div><div id="lc57">        <span style="color: rgb(0, 128, 0); font-weight: bold;">return</span> <span style="color: rgb(25, 23, 124);">$this</span><span style="color: rgb(102, 102, 102);">-&gt;</span><span style="color: rgb(125, 144, 41);">arr</span>[<span style="color: rgb(186, 33, 33);">'b'</span>];
</div><div id="lc58">    }
</div><div id="lc59">
</div><div id="lc60">}
</div><div id="lc61">
</div><div id="lc62"><span style="color: rgb(0, 128, 0); font-weight: bold;">class</span> <span style="color: rgb(0, 0, 255); font-weight: bold;">C</span>
</div><div id="lc63">{
</div><div id="lc64">    <span style="color: rgb(0, 128, 0); font-weight: bold;">private</span> <span style="color: rgb(25, 23, 124);">$arr</span> <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">array</span>();
</div><div id="lc65">
</div><div id="lc66">    <span style="color: rgb(0, 128, 0); font-weight: bold;">public</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">function</span> <span style="color: rgb(0, 0, 255);">__construct</span>(<span style="color: rgb(25, 23, 124);">$arr</span>)
</div><div id="lc67">    {
</div><div id="lc68">        <span style="color: rgb(25, 23, 124);">$array</span> <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">array</span>();
</div><div id="lc69">
</div><div id="lc70">        <span style="color: rgb(25, 23, 124);">$array</span>[<span style="color: rgb(102, 102, 102);">0</span>][<span style="color: rgb(186, 33, 33);">'c'</span>] <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(25, 23, 124);">$arr</span>[<span style="color: rgb(186, 33, 33);">'c'</span>];
</div><div id="lc71">        <span style="color: rgb(25, 23, 124);">$array</span>[<span style="color: rgb(102, 102, 102);">1</span>][<span style="color: rgb(186, 33, 33);">'d'</span>] <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(25, 23, 124);">$arr</span>[<span style="color: rgb(186, 33, 33);">'d'</span>];
</div><div id="lc72">
</div><div id="lc73">        <span style="color: rgb(25, 23, 124);">$this</span><span style="color: rgb(102, 102, 102);">-&gt;</span><span style="color: rgb(125, 144, 41);">arr</span>[<span style="color: rgb(102, 102, 102);">0</span>][<span style="color: rgb(186, 33, 33);">'a'</span>] <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(25, 23, 124);">$arr</span>[<span style="color: rgb(186, 33, 33);">'a'</span>];
</div><div id="lc74">        <span style="color: rgb(25, 23, 124);">$this</span><span style="color: rgb(102, 102, 102);">-&gt;</span><span style="color: rgb(125, 144, 41);">arr</span>[<span style="color: rgb(102, 102, 102);">0</span>][<span style="color: rgb(186, 33, 33);">'b'</span>] <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(25, 23, 124);">$arr</span>[<span style="color: rgb(186, 33, 33);">'b'</span>];
</div><div id="lc75">        <span style="color: rgb(25, 23, 124);">$this</span><span style="color: rgb(102, 102, 102);">-&gt;</span><span style="color: rgb(125, 144, 41);">arr</span>[<span style="color: rgb(102, 102, 102);">1</span>][<span style="color: rgb(186, 33, 33);">'xxx'</span>] <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(25, 23, 124);">$array</span>;
</div><div id="lc76">
</div><div id="lc77">    }
</div><div id="lc78">
</div><div id="lc79">    <span style="color: rgb(0, 128, 0); font-weight: bold;">public</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">function</span> <span style="color: rgb(0, 0, 255);">process_data</span>()
</div><div id="lc80">    {
</div><div id="lc81">        <span style="color: rgb(64, 128, 128); font-style: italic;">//.......</span>
</div><div id="lc82">    }
</div><div id="lc83">
</div><div id="lc84">    <span style="color: rgb(0, 128, 0); font-weight: bold;">public</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">function</span> <span style="color: rgb(0, 0, 255);">return_data</span>()
</div><div id="lc85">    {
</div><div id="lc86">        <span style="color: rgb(0, 128, 0); font-weight: bold;">return</span> <span style="color: rgb(25, 23, 124);">$this</span><span style="color: rgb(102, 102, 102);">-&gt;</span><span style="color: rgb(125, 144, 41);">arr</span>;
</div><div id="lc87">    }
</div><div id="lc88">}
</div></pre></div>
<p style="padding: 0pt; margin: 2em 0pt 1em; font-size: 0.8em; color: rgb(102, 102, 102);"><span style="padding: 0pt 1em; background-color: rgb(245, 245, 245);"> Colored with <a href="http://dumpz.org" style="color: rgb(51, 51, 51);">dumpz.org</a></span></p>
</pre><p>

Ну как, осознали? А теперь представим, что у нас есть таких классов не три, а триста. Все эти классы работают абсолютно нормально.  Они все получают некоторый набор данных, обрабатывают его и возвращают результаты. Результаты могут содержать уже изменённые данные, могут содержать первоначальные данные, а могут вообще не содержать никаких данных. Точно та же картина и при инициализации этих классов - данные всё те же, а форматы инициализации объектов разные. 
В реальной программе такое может произойти, например, с личными данными пользователя. Может существовать много классов, которым нужно использовать данные пользователя. Какой-то класс запросит все данные. Какому-то будет достаточно только электронного адреса и он запросит в конструкторе инициализацию объекта строковой переменной. Одно дело, если вы в существующей системе создаёте новый класс, берёте данные из базы и как-то их обрабатываете. Совсем другое, когда вы вынуждены пользоваться уже обработанными данными
и возникает ситуация, когда из нескольких объектов нужно получить одни и те же данные, и у этих данных разный формат. Конечно же вы получите, обработаете и вернёте данные. Снова в новом формате. И так до бесконечности. Рано или поздно, поддерживать систему станет практически невозможно. Даже если всё отлично задокументировано. 

</p><p>Пул данных как раз и решает эту проблему. Итак, <strong>пул данных - одно унифицированное хранилище данных, доступное из любой точки программы</strong>. 
Пул данных обычно является ключевым элементом архитектуры, так что имеет смысл разрабатывать его в начале проекта, а не в конце. Прежде чем разработать пул данных, нужно ввести ряд договорённостей, которым будут следовать все остальные объекты. 

</p><p>Во-первых, нужно всё таки убедиться, что архитектура построена так, что пул данных действительно доступен для любого объекта. Просто чтобы данные в пуле и данные в произвольном порядке не жили рука об руку в одной и той же программе. 

</p><p>Во-вторых, обычно подразумевается, что если данные попали в пул, то их больше можно не проверять. Действительно, пул данных - это не мусорка. Данные должны быть проверены, провалидированы и верифицированы перед записью в пул. Тогда, в любой точке программы, можно получить точные данные, не заботясь о том, кто их туда положил. 

</p><p>В-третьих, нужно разработать один формат для всех данных. Так, чтобы любая подпрограмма могла быть уверенной - она может рассчитывать на конкретный формат данных и этот формат данных не изменится. В противном случае, пул просто не будет иметь смысла. 

</p><p>В-четвёртых, нужно чётко понимать, что пул данных - это не мусорка, а поэтому не стоит хранить в нём временные переменные. Например, такое использование пула данных является недопустимым - 
</p>
<pre><div class="highlight" style="background: none repeat scroll 0% 0% rgb(248, 248, 248);"><pre style="line-height: 125%;"><div id="lc1"><span style="color: rgb(0, 128, 0); font-weight: bold;">class</span> <span style="color: rgb(0, 0, 255); font-weight: bold;">A</span>
</div><div id="lc2">{
</div><div id="lc3">    <span style="color: rgb(0, 128, 0); font-weight: bold;">private</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">function</span> <span style="color: rgb(0, 0, 255);">foo</span>()
</div><div id="lc4">    {
</div><div id="lc5">        <span style="color: rgb(25, 23, 124);">$a</span> <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(102, 102, 102);">5</span>;
</div><div id="lc6">        <span style="color: rgb(25, 23, 124);">$data_pool</span><span style="color: rgb(102, 102, 102);">-&gt;</span><span style="color: rgb(125, 144, 41);">set_data</span>(<span style="color: rgb(25, 23, 124);">$a</span>);
</div><div id="lc7">    }
</div><div id="lc8">
</div><div id="lc9">    <span style="color: rgb(0, 128, 0); font-weight: bold;">private</span> <span style="color: rgb(0, 128, 0); font-weight: bold;">function</span> <span style="color: rgb(0, 0, 255);">bar</span>()
</div><div id="lc10">    {
</div><div id="lc11">        <span style="color: rgb(25, 23, 124);">$a</span> <span style="color: rgb(102, 102, 102);">=</span> <span style="color: rgb(25, 23, 124);">$data_pool</span><span style="color: rgb(102, 102, 102);">-&gt;</span><span style="color: rgb(125, 144, 41);">get_data</span>(<span style="color: rgb(186, 33, 33);">'a'</span>);
</div><div id="lc12">    <span style="color: rgb(64, 128, 128); font-style: italic;">//$a == 5;</span>
</div><div id="lc13">    }
</div><div id="lc14">}
</div></pre></div>
<p style="padding: 0pt; margin: 2em 0pt 1em; font-size: 0.8em; color: rgb(102, 102, 102);"><span style="padding: 0pt 1em; background-color: rgb(245, 245, 245);"> Colored with <a style="color: rgb(51, 51, 51);" href="http://dumpz.org">dumpz.org</a></span></p>
</pre>
<p>И в-пятых, сам пул данных не имеет права данные изменять. Что положили, то и забрали. Хотя, если некоторый класс считает, что данные в пуле устарели и решает их перезаписать, пул должен с этим согласиться.

</p><p>Кроме этого, пул данных может содержать массу других особенностей, зависящих от конкретного проекта, а именно - мы можем ввести систему приоритетов и запретить чтение и/или запись данных объектам, которые не могут иметь доступа к этим данным; мы можем хранить данные в базе, в файле или в массиве; мы можем сделать пул объектом, а можем предоставить несколько глобальных функций. В общем, архитектура пула зависит от вашей задачи.

</p><p>Но хватит слов и перейдём к делу. Давайте разработаем простенький пул данных, который будет иметь уровни доступа и предоставлять пользователю операции записи и чтения.

Итак, у меня получилось следующее -(Исходный код примера &quot;Пул данных&quot; на PHP вы можете загрузить по ссылке <a href="http://easy4web.ru/?p=1178#sourcecode">Пул данных. Реализация на PHP.</a>)</p><p>

Вот такой вот пул данных. На самом деле, в реальной задаче можно разработать ещё и проверку типа сохраняемой переменной. А так же, определённый формат для каждого алиаса, т.е. чтобы любой набор переменных под алиасом был всегда одного и того же вида. В общем, полёт фантазии программиста ограничивается только бюджетом его заказчика :) 

</p><p>Резюмируя, нужно сказать, что <strong>пул данных является стандартом де-факто для сложных веб-систем</strong>, которые пишутся более чем одним программистом. 

Надеюсь, вы сегодня узнали что-то новое и интересное.

Всем удачи.</p>
<p>Другие интересные статьи, посвященные веб-разработке, расположены на сайте "<a href="http://easy4web.ru/">Веб-разработка? Это просто!</a>". Добро пожаловать.</p> 
<!-- " ' --></td>
</tr>
</table>
 </table>
</center>]]></description>
<guid isPermaLink="false">1449374</guid>
<pubDate>Tue, 31 May 2011 12:40:04 MSD</pubDate>
</item>
<item>
<title>&#x412;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x430;? &#x42D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;! &#x41F;&#x430;&#x440;&#x443; &#x441;&#x43B;&#x43E;&#x432; &#x43E; Wap &#x438; PDA &#x441;&#x430;&#x439;&#x442;&#x430;&#x445;
</title>
<link>http://archives.maillist.ru/55140/1434297.html?rss=1</link>
<description><![CDATA[<style type="text/css"><!-- p { 
     padding-left: 10px; 
     padding-right: 10px; 
     font: 14px/20px Veradana, Arial, sans-serif; 
} 
 
span.drop { 
     font: bold 60px /0.83em tahoma, sans-serif; 
     color: #0019ff; 
     float: left; 
     margin-right: 5px; 
     margin-top: 5px; 
} 
 
 .list { 
     background-color: #f5f5f5; 
     border: 1px solid #ededed; 
     padding: 10px; 
     margin: 10px 40px 10px 40px; 
     font-family: courier, monospace; 
} 
 
h1{ 
     font-family: Verdana, Arial, Sans-Serif; 
     color:#fcb300; 
     font-size:28px; 
     font-weight:bold; 
     padding: 10px 0 0 10px; 
     text-align:left; 
} 
 --></style>
    
<table width="100%" summary="" cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" style="background-color: #ffffff; background-image: ;">
<tr valign="top" align="left">
<td bgcolor="#ffffff" style="padding: 5px; background-color: #ffffff; background-image: ;"><p>Я уверен, что скоро персональные компьютеры повторят судьбу 
динозавров. Мейнфреймы, cloud-computing, лэптопы, мобильные устройства и
 нестандартные гаджеты с доступом к паутине рано или поздно окончательно
 победят большие и неповоротливые ящики, напичканные железяками. Обычные
 PC останутся только в малобюджетных гос. организациях и ВУЗах и, 
однажды, какой-нибудь всемирный консорциум типа ISO объявит об отмене 
поддержки стандартов для писюков. Рынок PC пережил свой пик в конце 
90-хх - начале 2000-хх и теперь из года в год показывает стабильное 
снижение продаж. Вычислительные мощности топовых ноутбуков вполне 
сопоставимы с вычислительными мощностями топовых PC. Конечно, топовые PC
 продолжают выигрывать, но для абсолютного большинства 
бизнес-пользователей производительности мобильных платформ хватает с 
огромным запасом. Последний форпост PC - это геймеры. Но, рано или 
поздно, они окончательно пересядут на специализированные игровые 
консоли, а для чата и сёрфинга заменят свои писюки на ноутбуки. 
Последняя проблема в мобильных устройствах - ёмкость батареи. Рано или 
поздно эта проблема будет разрешена и PC переместятся в пыльные музеи 
кремниевых микросхем.</p>
<p>Но пока этого события не произошло, посмотрим на всю нашу 
деятельность критическим взглядом. Сколько сайтов сегодня имеет 
мобильную версию? Имеет ли <strong>сайт вашей компании мобильную версию</strong>?
 Имеет ли мобильную версию ваш хоумпейдж? Или блог? Насколько удобно вам
 работать с удалённым ресурсом с помощью телефона? Вряд ли на все эти 
вопросы можно ответить однозначное и твёрдое да. Конечно, огромные 
порталы уже давно имеют свои мобильные версии. Но бизнес рунета 
почему-то шевелится крайне медленно. Моя компания даже &quot;дарит&quot; мобильную
 версию сайта в случае хорошего и жирного заказа. Хотя, с точки зрения 
бизнеса, владельцы доменов должны давным давно обратить внимание на 
сайты, оптимизированные для мобильных платформ.<img title="Далее&hellip;" class="mceWPmore mceItemNoResize" _mce_src="http://easy4web.ru/wp-includes/js/tinymce/plugins/wordpress/img/trans.gif" src="http://easy4web.ru/wp-includes/js/tinymce/plugins/wordpress/img/trans.gif" /></p>
<p>Представим себе обычный интернет-аукцион. Вы делаете бид. И уезжаете 
по делам. Вам очень хочется заполучить этот лот. Но ваш бид побили. 
Конечно, вы получите уведомление на email, но если ваш телефон не 
настроен на автоматическое получение почты, вам будет крайне 
проблематично ответить. С другой стороны, если аукцион не имеет 
мобильной версии, пользователь может просто отказаться от бида по многим
 причинам - громоздкое приложение на сравнительно маленьком дисплее, 
сравнительно медленный коннект и мелкие элементы управления, куча 
джаваскриптов, которые будут открываться на телефоне в новых окнах и 
жутко раздражать пользователя, в конце-концов, недружелюбные 
пользовательский интерфейс. Ведь то, что дружелюбно на огромном 
мониторе, абсолютно враждебно на маленьком телефонном экранчике. А между
 тем, отказ от бида - это прямой убыток, т.к. владелец аукциона получает
 процент от сделки. Звучит не очень радостно.</p>
<p>Окей, хватит лирики. Посмотрим на решение.</p>
<p>Специализированных решений пока два - <strong>WAP и PDA сайты</strong>. Основное отличие в том, что WAP - это протокол, а PDA - это просто вёрстка, заточенная под <strong>мобильные устройства</strong>. Что же выбрать? Давайте посмотрим.</p>
<p>Итак, WAP.<br />
Во-первых, разработка WAP-сайта будет стоить дороже, чем разработка 
PDA-версии. Просто потому, что все верстальщики отлично знают HTML, 
xHTML, XML и т.п., но мало кто из них знает <strong>WML</strong>. 
Конечно, WML мало чем отличается от обычного HTML, но тем не менее. 
Итак, разработчик должен знать WML для разработки WAP-сайтов. А значит, 
стоимость такого более квалифицированного разработчика будет выше. И 
стоимость сайта будет выше.</p>
<p>Дальше - сам протокол. Принципиально протокол WAP ничем не отличается
 от обычного HTTP. Просто разработчики мобильных устройств вместе с 
бюрократами решили стандартизировать передачу данных по беспроводному 
протоколу, придумали WAP и все бы ничего, если бы ОпСоСы из каких-то 
абсолютно неведомых соображений не решили, что строка байт полученная по
 протоколу WAP должна стоить в разы дороже той же самой строки, 
полученной по протоколу HTTP посредством одной и той же технологии 
(например, <strong>GPRS</strong>). Лично я подозреваю, что этот финт 
ушами был рассчитан исключительно на непрофессионалов, с которых можно 
просто содрать деньги за ещё одно непонятное слово, в данном случае - 
WAP.</p>
<p>Как пример, вот стоимость одного мегабайта у украинского ОпСоСа &quot;Киевстар GSM&quot; на момент написания статьи:</p>
<p>WAP: $1.6<br />
HTTP: $0.8<br />
Специальная услуга доступа в интернет с человеческими ценами: $0.63/сутки + $0.0063/мегабайт.</p>
<p>Исходя из этой сетки цен, можно вполне уверенно предположить, что 
фактически передача одного мегабайта стоит недороже $0.01 (сравниваем с 
WAP).</p>
<p>Нетрудно сделать выводы, что вашей версией WAP сайта будут пользоваться только полные отморозки-мажоры.</p>
<p>К тому же, произошло то, что и должно было произойти - если WAP пока 
ещё поддерживается, то всё больше производителей мобильных девайсов 
отказываются от поддержки WML в пользу xHTML во встроенных браузерах. 
Вопрос - зачем передавать по специализированному протоколу всё те же 
HTML данные? Ответ очевиден.</p>
<p>Резюмируя всё выше сказанное, можно утверждать, что <strong>создание WAP версии сайта неоправданно дважды</strong>
 - экономически, т.к. существует вполне реальный дефицит на 
WML-специалистов, и практически - т.к. WAP-версией сайта просто никто не
 будет пользоваться. В то же время, у пользователя существует 
определённый спектр проблем, которые возникают при попытке 
воспользоваться обычным сайтом с мобильного девайса. А это значит, что 
разработчики должны эти проблемы решать. На вопрос, решать ли эти 
проблемы в принципе, ответ вполне однозначен - решать, т.к. сегодня 
количество проданных смартфонов в два раза превышает количество 
проданных персональных компьютеров. Решение проблемы лежит не только в 
технической области, но и в экономической, а, значит, бизнесу также 
необходимо обратить самое пристальное внимание на свои веб-ресурсы.</p>
<!-- " ' --></td>
</tr>
</table>
 </table>
</center>]]></description>
<guid isPermaLink="false">1434297</guid>
<pubDate>Thu, 05 May 2011 18:46:03 MSD</pubDate>
</item>
<item>
<title>&#x412;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x430;? &#x42D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;! &#x41F;&#x435;&#x440;&#x435;&#x43C;&#x435;&#x43D;&#x43D;&#x44B;&#x435; &#x43F;&#x435;&#x440;&#x435;&#x43C;&#x435;&#x43D;&#x43D;&#x44B;&#x445;. &#x417;&#x430;&#x447;&#x435;&#x43C; &#x43E;&#x43D;&#x438; &#x43D;&#x443;&#x436;&#x43D;&#x44B;.
</title>
<link>http://archives.maillist.ru/55140/1427959.html?rss=1</link>
<description><![CDATA[<style type="text/css"><!-- p { 
     padding-left: 10px; 
     padding-right: 10px; 
     font: 14px/20px Veradana, Arial, sans-serif; 
} 
 
span.drop { 
     font: bold 60px /0.83em tahoma, sans-serif; 
     color: #0019ff; 
     float: left; 
     margin-right: 5px; 
     margin-top: 5px; 
} 
 
 .list { 
     background-color: #f5f5f5; 
     border: 1px solid #ededed; 
     padding: 10px; 
     margin: 10px 40px 10px 40px; 
     font-family: courier, monospace; 
} 
 
h1{ 
     font-family: Verdana, Arial, Sans-Serif; 
     color:#fcb300; 
     font-size:28px; 
     font-weight:bold; 
     padding: 10px 0 0 10px; 
     text-align:left; 
} 
 --></style>
    
<table width="100%" summary="" cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" style="background-color: #ffffff; background-image: ;">
<tr valign="top" align="left">
<td bgcolor="#ffffff" style="padding: 5px; background-color: #ffffff; background-image: ;"> <h1>Переменные переменных. Зачем они нужны.</h1>

<p>Всем привет. Сегодня мы поговорим о переменных переменных и выясним, зачем они всё таки нужны (или не нужны).</p><p>

В самом простом виде переменные переменных показаны в справке PHP. А именно -

<pre>
$a = 'hello';
$$a = 'world';
echo $a . ${$a};
</pre>
</p><p>

Подобная кривая конструкция выдаст на экран hello world. Другими словами, ${$a} эквивалентна вызову $hello. Не правда ли.. ужасно? Добавим сюда проблему неоднозначности, которая возникает при попытке обратиться к элементам массива (это подробно описано в справке по адресу <a href="http://ua.php.net/manual/en/language.variables.variable.php">http://ua.php.net/manual/en/language.variables.variable.php</a>), добавим сюда возможность добавлять к имени переменной любое количество знаков доллара, о которой обычно
не пишут в учебниках, и возникнет вполне закономерное недоумение - зачем это вообще нужно?
</p><p>

Самое главное правило, которого должен придерживаться любой разработчик в любом проекте - код пишется для людей, а не для машин. Это правило помимо негласного этикета в среде профессионалов в виде комментариев и отступов, ещё и экономически обоснованно. Дело в том что сегодня разработка ПО стремительно дешевеет (не без помощи демпинга индусов). Прямым следствием является то, что поддерживать код должно быть дешевле, чем его писать. Т.о. становится понятно, что читабельный, понятный и простой в понимании код,
куда как более ценен, чем процессинг формы на Brainfuck'e (кто не в курсе, пусть насладится <a href="http://en.wikipedia.org/wiki/Brainfuck">http://en.wikipedia.org/wiki/Brainfuck</a>), пусть даже на Brainfuck'e этот процессинг работает на 0.0001 секунду быстрее.
</p><p>

Добавим сюда огромные вычислительные возможности современных серверов, которые могут прожевать мегаметры самого бездарного кода в течение секунды и станет понятно, что деньги, затрачиваемые на поддержку, должны быть минимальными. Разработчик должен иметь возможность спокойно и быстро разобраться в коде, написанном соседней командой, даже через пару лет после финального релиза проекта. Реалии PHP вполне это позволяют - всё таки это скриптовый язык, а не ассемблер.</p><p> Продолжение статьи "<a href='http://easy4web.ru/?p=1109'>Переменные
переменных, зачем они нужны?</a>", а также другие интересные статьи, посвященные веб-разработке, Вы можете прочитать на сайте "<a href='http://easy4web.ru/'>Веб-разработка? Это просто!</a>".

</p>
<!-- " ' --></td>
</tr>
</table>
 </table>
</center>]]></description>
<guid isPermaLink="false">1427959</guid>
<pubDate>Mon, 25 Apr 2011 12:40:04 MSD</pubDate>
</item>
<item>
<title>&#x412;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x430;? &#x42D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;! &#x41F;&#x438;&#x432;&#x43E;&#x442; &#x438;&#x43B;&#x438; &#x441;&#x432;&#x43E;&#x434;&#x43D;&#x430;&#x44F; &#x442;&#x430;&#x431;&#x43B;&#x438;&#x446;&#x430;
</title>
<link>http://archives.maillist.ru/55140/1424815.html?rss=1</link>
<description><![CDATA[<style type="text/css"><!-- p { 
     padding-left: 10px; 
     padding-right: 10px; 
     font: 14px/20px Veradana, Arial, sans-serif; 
} 
 
span.drop { 
     font: bold 60px /0.83em tahoma, sans-serif; 
     color: #0019ff; 
     float: left; 
     margin-right: 5px; 
     margin-top: 5px; 
} 
 
 .list { 
     background-color: #f5f5f5; 
     border: 1px solid #ededed; 
     padding: 10px; 
     margin: 10px 40px 10px 40px; 
     font-family: courier, monospace; 
} 
 
h1{ 
     font-family: Verdana, Arial, Sans-Serif; 
     color:#fcb300; 
     font-size:28px; 
     font-weight:bold; 
     padding: 10px 0 0 10px; 
     text-align:left; 
} 
 --></style>
    
<table width="100%" summary="" cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" style="background-color: #ffffff; background-image: ;">
<tr valign="top" align="left">
<td bgcolor="#ffffff" style="padding: 5px; background-color: #ffffff; background-image: ;"><h1>Пивот или сводная таблица</h1>
<p>Всем привет. Сегодня мы коснёмся одной очень интересной темы, которая очень слабо освещена в рунете. Тема эта больше теоретическая, и, скорее всего, в обычных проектах вы с этим не столкнётесь никогда, но уж если столкнётесь и не будете знать, что перед вами, пара-тройка бессонных ночей вам гарантированна. С другой стороны, если перед вами возникнет задача, где можно использовать пивот, вы сможете резко повысить производительность вашей системы. А для веб производительность всегда была критична. Попробуем
же потратить пол часа сейчас и отлично выспаться потом, когда-нибудь в будущем :)</p><p>
Итак, пивот. Что это такое и с чем его едят? Скажу сразу, к пиву это не имеет никакого отношения. А имеет отношения к реляционным базам данных, например, к MySQL. Пивот - это разворот таблицы. Или таблица разворота. Вот видите, это уже, практически, пивот. Придумали эту штуку два оч. умных дядьки - Бил Джелен и Майк Александер. Подробнее об истории пивота можно посмотреть в английской википедии (http://en.wikipedia.org/wiki/Pivot_table).</p><p>
Приведём пример, чтобы понять, что такое пивот, т.к. без примера и на словах понять это практически невозможно (если Эйнштейн не был вашим дедушкой, а Тьюринг - братом, конечно).</p><p>
Пусть есть исходная MySQL таблица, которая хранит результаты экзаменов -
<pre>
CREATE TABLE exams (
  pkey int(11) NOT NULL auto_increment,
  name varchar(15),
  exam int,
  score int,
  PRIMARY KEY  (pkey)
);

+------+------+------+-------+
| pkey | name | exam | score |
+------+------+------+-------+
|    1 | Bob  |    1 |    75 |
|    2 | Bob  |    2 |    77 |
|    3 | Bob  |    3 |    78 |
|    4 | Bob  |    4 |    80 |
|    5 | Sue  |    1 |    90 |
|    6 | Sue  |    2 |    97 |
|    7 | Sue  |    3 |    98 |
|    8 | Sue  |    4 |    99 |
+------+------+------+-------+
</pre>
</p><p>Это обычная плоская таблица MySQL. Автоинкрементный первичный ключ нас вообще не интересует. В остальных колонках хранится номер экзамена и количество баллов, которые студент по имени name умудрился набрать (судя по всему, Sue вообще никогда не прогуливает). Понятно, что exam может быть в свою очередь внешним ключом для ссылки на другую таблицу с названием экзаменов, с экзаменаторами и т.д. Нам это не интересно.</p><p>
При пивоте по экзамену результирующая таблица будет выглядеть так -
<pre>
+------+-------+-------+-------+-------+
| name | exam1 | exam2 | exam3 | exam4 |
+------+-------+-------+-------+-------+
| Bob  |    75 |    77 |    78 |    80 |
| Sue  |    90 |    97 |    98 |    99 |
+------+-------+-------+-------+-------+
</pre></p><p>
Сразу видно, насколько эта таблица полезнее. Например, если эти данные вернуть в PHP приложение, то обладая тем же набором данных мы сделаем всего лишь две итерации цикла для выборки всех данных из таблицы. Для первой плоской таблицы нам бы пришлось гонять цикл while все восемь раз. Согласитесь - прирост производительности в 4 раза - серьёзный аргумент за то, чтобы задуматься об использовании такого приёма. Как же получить такую пивот-таблицу? Для начала рассмотрим нематематический способ. Он ничем не хуже математического,
но изначально пивот был изобретён для осуществления каких-то более осмысленных действий над данными, чем простая выборка, например - вычисление средних значений, вычисление разниц, использование каких-нибудь статистических функций с выбранными данными и т.п.</p><p>
Продолжение статьи "<a href='http://easy4web.ru/?p=1099'>Пивот или сводная таблица</a>" а также другие статьи, посвященные веб-разработке, Вы можете прочитать на сайте "<a href='http://easy4web.ru/'>Веб-разработка? Это просто!</a>".
<!-- " ' --></td>
</tr>
</table>
 </table>
</center>]]></description>
<guid isPermaLink="false">1424815</guid>
<pubDate>Wed, 20 Apr 2011 10:42:07 MSD</pubDate>
</item>
<item>
<title>&#x412;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x430;? &#x42D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;! &#x41D;&#x43E;&#x432;&#x43E;&#x441;&#x442;&#x438; &#x432;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x438;.
</title>
<link>http://archives.maillist.ru/55140/1389610.html?rss=1</link>
<description><![CDATA[<style type="text/css"><!-- p { 
     padding-left: 10px; 
     padding-right: 10px; 
     font: 14px/20px Veradana, Arial, sans-serif; 
} 
 
span.drop { 
     font: bold 60px /0.83em tahoma, sans-serif; 
     color: #0019ff; 
     float: left; 
     margin-right: 5px; 
     margin-top: 5px; 
} 
 
 .list { 
     background-color: #f5f5f5; 
     border: 1px solid #ededed; 
     padding: 10px; 
     margin: 10px 40px 10px 40px; 
     font-family: courier, monospace; 
} 
 
h1{ 
     font-family: Verdana, Arial, Sans-Serif; 
     color:#fcb300; 
     font-size:28px; 
     font-weight:bold; 
     padding: 10px 0 0 10px; 
     text-align:left; 
} 
 --></style>
    
<table width="100%" summary="" cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" style="background-color: #ffffff; background-image: ;">
<tr valign="top" align="left">
<td bgcolor="#ffffff" style="padding: 5px; background-color: #ffffff; background-image: ;"><h1>Отличная спецификация про HTML5 для разработчиков</h1>
<p>По ссылке <a href="http://developers.whatwg.org/">HTML5. A technical specification for Web developers</a> доступна отличная спецификация по HTML5 для веб-разработчиков. В отличие от <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/">полной HTML5-спецификации</a> из этой редакции убрана вся информация, знать которую нужно только разработчикам браузеров. Основополагающими отличиями данной редакции являются читабельность и удобная навигация. </p>

<h1>Регистратор GoDaddy продает домены по 1.18$</h1>
<p>Регистратор <a href="http://www.godaddy.com/default.aspx">GoDaddy</a> объявил акцию - регистрация и трансфер домена в зоне .COM, .US, .MOBI, .BIZ, .NET, .ORG, .CA, .CO.UK, .IN всего за 1.18$.<br />Акция действует до первых 10000 доменов или до 20 марта. Оплата регистрации только по карте, с одного аккаунта можно зарегистрировать только один домен.
</p>
<!-- " ' --></td>
</tr>
</table>
</table>
</center>]]></description>
<guid isPermaLink="false">1389610</guid>
<pubDate>Tue, 22 Feb 2011 18:26:03 MSK</pubDate>
</item>
<item>
<title>&#x412;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x430;? &#x42D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;! &#x411;&#x443;&#x43A;&#x43C;&#x430;&#x440;&#x43A;&#x43B;&#x435;&#x442;&#x44B; &#x438;&#x43B;&#x438; &#x43A;&#x430;&#x43A; &#x441;&#x43A;&#x430;&#x447;&#x430;&#x442;&#x44C; &#x430;&#x443;&#x434;&#x438;&#x43E;&#x444;&#x430;&#x439;&#x43B;&#x44B; &#x441; &#x441;&#x430;&#x439;&#x442;&#x430; vkontakte?
</title>
<link>http://archives.maillist.ru/55140/1343255.html?rss=1</link>
<description><![CDATA[<style type="text/css"><!-- p { 
     padding-left: 10px; 
     padding-right: 10px; 
     font: 14px/20px Veradana, Arial, sans-serif; 
} 
 
span.drop { 
     font: bold 60px /0.83em tahoma, sans-serif; 
     color: #0019ff; 
     float: left; 
     margin-right: 5px; 
     margin-top: 5px; 
} 
 
 .list { 
     background-color: #f5f5f5; 
     border: 1px solid #ededed; 
     padding: 10px; 
     margin: 10px 40px 10px 40px; 
     font-family: courier, monospace; 
} 
 
h1{ 
     font-family: Verdana, Arial, Sans-Serif; 
     color:#fcb300; 
     font-size:28px; 
     font-weight:bold; 
     padding: 10px 0 0 10px; 
     text-align:left; 
} 
 --></style>
    
<table width="100%" summary="" cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" style="background-color: #ffffff; background-image: ;">
<tr valign="top" align="left">
<td bgcolor="#ffffff" style="padding: 5px; background-color: #ffffff; background-image: ;"><h1>Букмарклеты или как скачать аудиофайлы с сайта vkontakte?</h1>

<p>Сегодня я собираюсь рассказать про одну интересную технологию, как мне кажется, с большим будущим. Называется эта технология <strong>bookmarklets</strong>(<strong>букмарклеты</strong>).
Букмарклет - это маленькая JavaScript-программа, оформленная в виде <em>javascript</em>-ссылки и вызываемая как браузерная закладка. Итак, мы знаем, что в атрибуте href гипертекстовой ссылки можно указать url любой существующей страницы, обычно url этот выглядит примерно так <em>&lt;a href='http://address.org/path/index.html'&gt;ссылка&lt;/a&gt;</em>, в данном случае <strong>http:</strong> - это указание протокола обмена, а все остальное - указание сервера, пути к файлу, и имени файла, к которому обратится браузер
после клика на ссылке. Так вот, существует ряд протоколов, таких как, например, <em>http:</em> (протокол гипертекстового обмена), <em>ftp:</em>(протокол обмена файлами), <em>file:</em>(протокол загрузки локальных файлов пользователя).
</p><p>
Помимо этого существует еще один интересный протокол <em>javascript:</em>, который мы и будем использовать для создания букмарклетов. Выглядит это примерно так:
</p><p>
<em>&lt;a href='javascript:alert('Hello, world');'&gt;букмарклет&lt;/a&gt;</em> при щелчке по <a title="этой ссылке" href="javascript:alert('Hello, world');">этой ссылке</a>, выполнится команда alert('Hello, world'); Проверьте, как это работает.
</p><p>
Попробуем теперь перетащить эту ссылку в панель закладок браузера, или щелкнув на ней правой кнопкой добавить ее в закладки. После того, как ссылка сохранена в закладки, можно в любой момент выбрать ее и выполнить.
</p><p>
Попробуем немного усложнить нашу закладку, пусть тепреь она выводит адрес документа из которого она вызвана. Вот этот букмарклет:
</p><p>
<em>&lt;a href='javascript:alert(document.location);'&gt;Адрес текущей страницы&lt;/a&gt;</em>.
</p><p>
Добавьте эту ссылку (<a href="javascript:alert(document.location);">Адрес текущей страницы</a>) в закладки и вызовите ее, открыв предварительно в браузере какую-нибудь интернет-страницу, например сайт Яндекса. Вы увидите всплывающее оповещение с указанием адреса текущей страницы. Из этого можно сделать один очень важный вывод: букмарклет, вызванный из браузера, как закладка, выполняется в контексте текущей, открытой в браузере страницы. А этот факт дает нам неограниченный доступ к изменению данных на странице,
и к извлечению из страницы любых данных, вплоть до полной замены содержимого этой страницы.
</p><p>
К сожалению, длина скрипта, сохраняемого в закладке ограничена. Причем, для разных браузеров она разная. Не углубляясь в различия между браузерами, можно сказать, что длина эта ограничена для различных браузеров от 488 до 2084 символов, что не может не огорчить. В принципе, для несложных букмарклетов нам хватит и этой длины, но что делать, если нам хочется большего? Что если мы хотим написать скрипт, который производит достаточно сложную обработку загруженной страницы, и в 2 кБ скрипта нам никак не уложиться?
</p><p>
Для этого можно использовать способ, заключающийся в следующем: сам букмарклет представляет собой небольшой скрипт, у которого есть лишь одно предназначение - загрузить основной скрипт и запустить его на выполнение.
</p><p>
Созданием этого скрипта мы сейчас и займемся. Но для начала замечу вот что. Какой бы скрипт мы ни создавали, практически всегда в нем мы будем объявлять создание новых функций и новых переменных. А создаваться они будут в контексте загруженной пользователем страницы, где до нас уже могут существовать какие-либо переменные и функции. Понятно, что мы никак не можем предугадать, какие имена будут у этих переменных, а значит, создавая свои собственные, мы можем случайно переопределить уже существующие переменные,
внеся тем самым непредсказуемые изменения в логику работы пользовательских скриптов. Таким образом, запустив букмарклет, помимо его полезной работы, мы можем получить и совершенно непредсказуемые побочные явления, связанные с перопределением переменных.
</p><p>
Самый удобный способ избавиться от этих эффектов - применить анонимную функцию. Анонимные функции определяются также как и именованные, за исключением того факта, что им не присваивается имя.</p><p>
Продолжение статьи "<a href='http://easy4web.ru/?p=805'>Букмарклеты или как скачать аудиофайлы с сайта vkontakte?</a>" и многие другие статьи про тонкости веб-разработки Вы можете прочитать на сайте "<a href='http://easy4web.ru/'>Веб-разработка? Это просто!</a>".
<!-- " ' --></td>
</tr>
</table>
</table>
</center>]]></description>
<guid isPermaLink="false">1343255</guid>
<pubDate>Mon, 13 Dec 2010 12:16:03 MSK</pubDate>
</item>
<item>
<title>&#x412;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x430;? &#x42D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;! AJAX &#x43F;&#x440;&#x438; &#x43F;&#x43E;&#x43C;&#x43E;&#x449;&#x438; DataContractJsonSerializer &#x438; ashx-handler
</title>
<link>http://archives.maillist.ru/55140/1316418.html?rss=1</link>
<description><![CDATA[<style type="text/css"><!-- p { 
     padding-left: 10px; 
     padding-right: 10px; 
     font: 14px/20px Veradana, Arial, sans-serif; 
} 
 
span.drop { 
     font: bold 60px /0.83em tahoma, sans-serif; 
     color: #0019ff; 
     float: left; 
     margin-right: 5px; 
     margin-top: 5px; 
} 
 
 .list { 
     background-color: #f5f5f5; 
     border: 1px solid #ededed; 
     padding: 10px; 
     margin: 10px 40px 10px 40px; 
     font-family: courier, monospace; 
} 
 
h1{ 
     font-family: Verdana, Arial, Sans-Serif; 
     color:#fcb300; 
     font-size:28px; 
     font-weight:bold; 
     padding: 10px 0 0 10px; 
     text-align:left; 
} 
 --></style>
    
<table width="100%" summary="" cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" style="background-color: #ffffff; background-image: ;">
<tr valign="top" align="left">
<td bgcolor="#ffffff" style="padding: 5px; background-color: #ffffff; background-image: ;"><h1>AJAX при помощи DataContractJsonSerializer и ashx-handler</h1>
<p>В продолжение разговора про AJAX хочу написать несколько статей, описывающих создание <strong>AJAX-приложений</strong> с применением различных подходов. А подходы эти в принципе могут отличаться в следующих ключевых моментах:
<ol>
 <li>Тип клиентской JS-библиотеки</li>
 <li>Тип серверного ответчика</li>
 <li>Способ сериализации данных</li>
 <li>Тип передаваемых данных</li>
</ol>
Как видим, здесь есть где развернуться. </p>

<p>Расскажу подробнее о каждом из пунктов.</p>

<ol>
<li>Тип клиентской JS-библиотеки.
<p>
Это тот скрипт, который работает в браузере пользователя. Какую бы библиотеку Вы не использовали, в недрах ее для асинхронного обмена данными в любом случае будет использоваться объект XmlHTTPRequest. Я лично пользовался такими библиотеками как: ExtJS, <strong>jQuery</strong>, prototype.js, ATLAS. Сложно сравнивать эти библиотеки, все они хороши, каждая по своему.
</p></li>
<li>Тип серверного ответчика.
<p>
Прежде всего серверный ответчик характеризует язык серверной реализации, это может быть PHP, ASP.NET, Java, Ruby, Python и много других страшных слов. :) В каждом языке есть свои типы серверных ответчиков. Говоря про ASP.NET, я могу выделить WebServices (*.asmx), <strong>Generic Handlers (*.ashx)</strong>.</p></li>

<li>Способ <em>сериализации данных</em>.
<p>
Их можно сериализовать "вручную", то есть простой конкатенацией строк, можно использовать встроенные в серверную платформу объекты, например <strong>DataContractJsonSerializer</strong>, который имеется в ASP.NET.</p></li>

<li>Тип передаваемых данных.
<p>
Данные можно передавать в собственном формате, можно в виде JSON-строки, XML-строки, или же передавая строку с готовой HTML-разметкой. Вариантов масса, выбор зависит от контекста задачи.
</p></li></ol>
<p>В данной статье я собираюсь рассмотреть вариант релизации AJAX-обмена на основе компонентов:</p>

<ol>
<li><strong>Клиентская библиотека - jQuery,</strong></li>

<li><strong>Серверный ответчик - Generic Handler (*.ashx),</strong></li>

<li><strong>Способ сериализации - DataContractJsonSerializer,</strong></li>

<li><strong>Тип данных - HTML-разметка, упакованная в JSON-строку.</strong></li>

</ol>
<p>Чтобы не создавать бесполезный код, заставим наше приложение отображать на странице структуру некоторой папки, и позволяющей даже ходить по вложенным в нее папкам и скачивать любые файлы. Для простоты рассмотрения AJAX-обмена, вся заявленная функциональность будет вынесена в отдельные классы и оставлена без моих комментариев, а вот все что касается AJAX будет мною подробно рассмотрено и прокомментировано.</p>
<p>Продолжение статьи "<a href='http://easy4web.ru/?p=912'>AJAX при помощи DataContractJsonSerializer и ashx-handler</a>" и другие полезные статьи, посвященный веб-разработке Вы можете прочитать на сайте "<a href='http://easy4web.ru'>Веб-разработка? Это просто!</a>"</p>
<!-- " ' --></td>
</tr>
</table>
</table>
</center>]]></description>
<guid isPermaLink="false">1316418</guid>
<pubDate>Tue, 02 Nov 2010 13:21:03 MSK</pubDate>
</item>
<item>
<title>&#x412;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x430;? &#x42D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;! &#x415;&#x449;&#x435; &#x43F;&#x430;&#x440;&#x430; &#x442;&#x440;&#x44E;&#x43A;&#x43E;&#x432;
</title>
<link>http://archives.maillist.ru/55140/1273921.html?rss=1</link>
<description><![CDATA[<style type="text/css"><!-- p { 
     padding-left: 10px; 
     padding-right: 10px; 
     font: 14px/20px Veradana, Arial, sans-serif; 
} 
 
span.drop { 
     font: bold 60px /0.83em tahoma, sans-serif; 
     color: #0019ff; 
     float: left; 
     margin-right: 5px; 
     margin-top: 5px; 
} 
 
 .list { 
     background-color: #f5f5f5; 
     border: 1px solid #ededed; 
     padding: 10px; 
     margin: 10px 40px 10px 40px; 
     font-family: courier, monospace; 
} 
 
h1{ 
     font-family: Verdana, Arial, Sans-Serif; 
     color:#fcb300; 
     font-size:28px; 
     font-weight:bold; 
     padding: 10px 0 0 10px; 
     text-align:left; 
} 
 --></style>
    
<table width="100%" summary="" cellspacing="3" cellpadding="3" border="0" bgcolor="#ffffff" style="background-color: #ffffff; background-image: ;">
<tr valign="top" align="left">
<td bgcolor="#ffffff" style="padding: 5px; background-color: #ffffff; background-image: ;"><h1>DOM: вытаскиваем текст вне тегов</h1>
<p>Данная публикация открывает новую рубрику в блоге. Рубрика называется &quot;Кратко&quot;. В ней я буду публиковать совсем кратенькие статьи - рецепты, темы для которых чаще всего буду брать из статистики поискового трафика. То есть, если я вижу, что человек пришел на мой сайт по некоему запросу, и ответа на вопрос на моем сайте нет, то я буду писать на них ответы и может когда-нибудь мой ответ пригодится.</p>

<p>Анализируя поисковый трафик, я обнаружил вопрос &quot;вытащить текст вне тегов&quot;, делюсь рецептом. Собственно, каждая ситуация уникальна, но в общем случае, нужно отыскать в DOM-структуре некий строго определенный элемент и уже относительно него отыскать нужный нам текст.</p>

<p>В нашем случае документ представляет собой два дива с заданными строго идентификаторами, между которыми расположен искомый текстовый элемент.  При помощи getElementById мы на ходим элемент div1, а затем при помощи nextSibling добираемся до текстового узла, ведь он стоит следующим в DOM-структуре. Получить его значение можно при помощи свойства nodeValue.</p>

<p>Вот и весь рецепт.</p>
<em><pre name="code" class="html">&lt;html&gt;<br />&lt;head&gt;<br /> &lt;title&gt;Hello!&lt;/title&gt;<br /> &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;<br /> &lt;script type=&quot;text/javascript&quot;&gt;<br /> function getText()<br /> {<br /> var div1 = document.getElementById(&quot;div1&quot;);<br /> div1.nextSibling.nodeValue = &quot;Поменял текст&quot;;<br /> }<br /> &lt;/script&gt;<br />&lt;/head&gt;<br />&lt;body&gt;<br />&lt;div id=&quot;div1&quot;&gt;Предшествующий
блок&lt;/div&gt;<br />Это текст я хочу получить<br />&lt;div id=&quot;div2&quot;&gt;Замыкающий блок&lt;/div&gt;<br />&lt;input type=&quot;button&quot; value=&quot;Start!&quot; onclick=&quot;getText()&quot;&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;</pre></em>

<h1>DIV всплывающий поверх flash-баннера</h1>
<p>В процессе создания сайтов, столкнулся однажды с проблемой выражаемой в том, что flash-баннер, размещенный на странице, закрывает собой всплывающий DIV содержащий в себе меню навигации.</p>

<p>Сам этот DIV имеет z-index больше нуля, и когда на странице нет никакой Flash-анимации, этот DIV плавает поверх страницы. Однако, как только появляется Flash-баннер, то баннер этот рендерится поверх любых плавающих DIV-ов.</p>

<p>Как и все гениальное, решение оказалось простым. Достаточно тегам OBJECT и EMBED добавить атрибут wmode со значение opaque.</p>

<p>Выглядеть это должно как-то так:
<em><pre name="code" class="html">&lt;OBJECT wmode=&quot;opaque&quot; ...&gt;<br />&lt;EMBED ...&gt;<br />&lt;PARAM name=&quot;wmode&quot; value=&quot;opaque&quot;&gt;<br />&lt;/EMBED&gt;<br />&lt;/OBJECT&gt;</pre></em></p>
<p>А связано это с тем, что по умолчанию, параметр этот принимает значение <em>window</em>, а это говорит браузеру, что флешку необходимо отрисовывать поверх страницы и всего, что на ней находится. Другие значения параметра <em>wmode - opaque и transparent</em>. Последний ко всему прочему позволяет задавать прозрачный фон для DIV'а, отображаемого поверх флешки. Учтите, что подобные игры с прозрачностью могут заметно ухудшать производительность работы браузера.</p>
<br /><br /><br />
<!-- " ' --></td>
</tr>
</table>
</table>
</center>]]></description>
<guid isPermaLink="false">1273921</guid>
<pubDate>Thu, 26 Aug 2010 11:46:03 MSD</pubDate>
</item>
<item>
<title>&#x412;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x430;? &#x42D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;! &#x41A;&#x440;&#x43E;&#x441;&#x434;&#x43E;&#x43C;&#x435;&#x43D;&#x43D;&#x430;&#x44F; &#x43F;&#x435;&#x440;&#x435;&#x434;&#x430;&#x447;&#x430; &#x434;&#x430;&#x43D;&#x43D;&#x44B;&#x445; &#x43C;&#x435;&#x436;&#x434;&#x443; html-&#x441;&#x442;&#x440;&#x430;&#x43D;&#x438;&#x446;&#x430;&#x43C;&#x438;
</title>
<link>http://archives.maillist.ru/55140/1211273.html?rss=1</link>
<description><![CDATA[<style type="text/css"><!-- p { 
     padding-left: 10px; 
     padding-right: 10px; 
     font: 14px/20px Veradana, Arial, sans-serif; 
} 
 
span.drop { 
     font: bold 60px /0.83em tahoma, sans-serif; 
     color: #0019ff; 
     float: left; 
     margin-right: 5px; 
     margin-top: 5px; 
} 
 
 .list { 
     background-color: #f5f5f5; 
     border: 1px solid #ededed; 
     padding: 10px; 
     margin: 10px 40px 10px 40px; 
     font-family: courier, monospace; 
} 
 
h1{ 
     font-family: Verdana, Arial, Sans-Serif; 
     color:#fcb300; 
     font-size:28px; 
     font-weight:bold; 
     padding: 10px 0 0 10px; 
     text-align:left; 
} 
 --></style>
    
<table width="100%" summary="" cellspacing="3" cellpadding="3" border="0" bgcolor="#ffffff" style="background-color: #ffffff; background-image: ;">
<tr valign="top" align="left">
<td bgcolor="#ffffff" style="padding: 5px; background-color: #ffffff; background-image: ;"><h1>Кросдоменная передача данных между html-страницами</h1>
<p>
Итак, представим себе ситуацию, что на некотором сайте в некоторой форме есть поле, в которое нужно ввести логин пользователя, но не свой собственный, а чужой логин, предположим, пользователя, которого надо добавить в друзья или в черный список. Но посетитель может не помнить наизусть, как пишется этот логин, а потому мы сделаем так, чтобы он мог выбрать его из списка, причем список этот должен открыться в отдельном окне и там помимо списка логинов пользователей должны отображаться еще и их фотографии, ФИО,
возраст и т.д. Предположим, что мы даже создали такую страницу со списком пользователей. Возникает вопрос - <em>как передать из одного окна браузера в другое окно некоторые данные</em> (в данном случае это - логин пользователя)?</p>

<p>Справочник по JavaScript и объектной документной модели DOM говорит нам, что для открытия нового окна нужно использовать метод <strong>window.open()</strong>, а для доступа из "дочернего" окна в "родительское" (то есть то, которое и породило новое окно) нужно использовать указатель <strong>opener</strong>.</p>

<p>Здесь все просто, и я не стал бы писать эту статью, если бы хотел рассказать только про это.</p>

<p>А хочу я теперь рассказать о том, как быть если окна эти расположены в разных доменах. Когда такое может произойти? Предположим, есть Ваш форум, а есть специализированный сервис для загрузки и хранения фотографий и вот теперь владелец форума хочет договориться с владельцем фото-сервиса, что на форму он разместит кнопку "Добавить изображение", которая будет открывать окно созданное в рамках фото-сервиса, в этом окне пользователь загрузит фотографии, а затем по нажатию кнопки "ОК" ссылки на фотографии скопируются
в окно редактирования сообщения на форуме. Как видим, здесь есть два окна в разных доменах и нам нужно передать текст из одного окна в другое.</p>

<p>"Что тут сложного?" - спросите вы. А давайте попробуем.</p>

<p>Продолжение статьи <a href='http://easy4web.ru/?p=836'>"Кросдоменная передача данных между html-страницами"</a>, а также другие статьи, посвященные веб-разработке, вы можете прочитать на сайте <a href='http://easy4web.ru/'>"Веб-разработка? Это просто!"</a></p>
<!-- " ' --></td>
</tr>
</table>
</table>
</center>]]></description>
<guid isPermaLink="false">1211273</guid>
<pubDate>Thu, 29 Apr 2010 17:11:09 MSD</pubDate>
</item>
<item>
<title>&#x412;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x430;? &#x42D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;! &#x412; &#x43D;&#x430;&#x448;&#x435;&#x43C; &#x431;&#x43B;&#x43E;&#x433;&#x435; &#x43F;&#x43E;&#x44F;&#x432;&#x438;&#x43B;&#x441;&#x44F; &#x444;&#x43E;&#x440;&#x443;&#x43C;.
</title>
<link>http://archives.maillist.ru/55140/1181881.html?rss=1</link>
<description><![CDATA[<style type="text/css"><!-- p { 
     padding-left: 10px; 
     padding-right: 10px; 
     font: 14px/20px Veradana, Arial, sans-serif; 
} 
 
span.drop { 
     font: bold 60px /0.83em tahoma, sans-serif; 
     color: #0019ff; 
     float: left; 
     margin-right: 5px; 
     margin-top: 5px; 
} 
 
 .list { 
     background-color: #f5f5f5; 
     border: 1px solid #ededed; 
     padding: 10px; 
     margin: 10px 40px 10px 40px; 
     font-family: courier, monospace; 
} 
 
h1{ 
     font-family: Verdana, Arial, Sans-Serif; 
     color:#fcb300; 
     font-size:28px; 
     font-weight:bold; 
     padding: 10px 0 0 10px; 
     text-align:left; 
} 
 --></style>
<table summary="" cellspacing="5" cellpadding="5" border="0" bgcolor="#ffffff" style="background-color: #ffffff; background-image: ;">
<tr valign="top" align="left">
<td bgcolor="#ffffff" style="padding: 5px; background-color: #ffffff; background-image: ; border: solid 1px #dddddd;"><h1>В нашем блоге появился форум.</h1><br/><br/>
<a href="http://easy4web.ru/forum/">Ссылка на форум</a>
<!-- " ' --></td>
</tr>
</table>]]></description>
<guid isPermaLink="false">1181881</guid>
<pubDate>Tue, 16 Mar 2010 22:15:40 MSK</pubDate>
</item>
<item>
<title>&#x412;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x430;? &#x42D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;! &#x412; &#x43D;&#x430;&#x435;&#x448;&#x43C; &#x431;&#x43B;&#x43E;&#x433;&#x435; &#x43F;&#x43E;&#x44F;&#x432;&#x438;&#x43B;&#x441;&#x44F; &#x444;&#x43E;&#x440;&#x443;&#x43C;.
</title>
<link>http://archives.maillist.ru/55140/1181879.html?rss=1</link>
<description><![CDATA[<style type="text/css"><!-- p { 
     padding-left: 10px; 
     padding-right: 10px; 
     font: 14px/20px Veradana, Arial, sans-serif; 
} 
 
span.drop { 
     font: bold 60px /0.83em tahoma, sans-serif; 
     color: #0019ff; 
     float: left; 
     margin-right: 5px; 
     margin-top: 5px; 
} 
 
 .list { 
     background-color: #f5f5f5; 
     border: 1px solid #ededed; 
     padding: 10px; 
     margin: 10px 40px 10px 40px; 
     font-family: courier, monospace; 
} 
 
h1{ 
     font-family: Verdana, Arial, Sans-Serif; 
     color:#fcb300; 
     font-size:28px; 
     font-weight:bold; 
     padding: 10px 0 0 10px; 
     text-align:left; 
} 
 --></style>
<table summary="" cellspacing="5" cellpadding="5" border="0" bgcolor="#ffffff" style="background-color: #ffffff; background-image: ;">
<tr valign="top" align="left">
<td bgcolor="#ffffff" style="padding: 5px; background-color: #ffffff; background-image: ; border: solid 1px #dddddd;"><h1>В нашем блоге появился форум. </h1><p>Именно так.</p><p><br />
Теперь вы можете не только комментировать наши статьи, но и создавать 
собственные посты. Если вас интересует любой вопрос связанный с 
веб-разработкой, мы и наши посетители постараемся на него ответить.</p><p><br />
Если вам есть что сказать &ndash; пишите на форуме. Добро пожаловать.
</p>
<!-- " ' --></td>
</tr>
</table>]]></description>
<guid isPermaLink="false">1181879</guid>
<pubDate>Tue, 16 Mar 2010 22:09:37 MSK</pubDate>
</item>
<item>
<title>&#x412;&#x435;&#x431;-&#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x430;? &#x42D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;! &#x420;&#x435;&#x430;&#x43B;&#x438;&#x437;&#x430;&#x446;&#x438;&#x44F; &#x447;&#x430;&#x442;&#x430; &#x43D;&#x430; ASP.NET &#x441; &#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x435;&#x43C; Long Polling
</title>
<link>http://archives.maillist.ru/55140/1179838.html?rss=1</link>
<description><![CDATA[<style type="text/css"><!-- p { 
     padding-left: 10px; 
     padding-right: 10px; 
     font: 14px/20px Veradana, Arial, sans-serif; 
} 
 
span.drop { 
     font: bold 60px /0.83em tahoma, sans-serif; 
     color: #0019ff; 
     float: left; 
     margin-right: 5px; 
     margin-top: 5px; 
} 
 
 .list { 
     background-color: #f5f5f5; 
     border: 1px solid #ededed; 
     padding: 10px; 
     margin: 10px 40px 10px 40px; 
     font-family: courier, monospace; 
} 
 
h1{ 
     font-family: Verdana, Arial, Sans-Serif; 
     color:#fcb300; 
     font-size:28px; 
     font-weight:bold; 
     padding: 10px 0 0 10px; 
     text-align:left; 
} 
 --></style>
<table summary="" cellspacing="5" cellpadding="5" border="0" bgcolor="#ffffff" style="background-color: #ffffff; background-image: ;">
<tr valign="top" align="left">
<td bgcolor="#ffffff" style="padding: 5px; background-color: #ffffff; background-image: ; border: solid 1px #dddddd;"><h1>Реализация чата на ASP.NET с использованием Long Polling</h1>
<p>
Бродя по просторам интернета, на одном из сайтов я увидел простой чат. Просмотрев страницу в <em>FireBug </em>я понял, что никакими апплетами там и не пахнет, а значит чат реализован на простом <em>JavaScript</em>.</p><p>

Я подключился к нему из нескольких браузеров и удивился, что второй браузер реагирует на сообщения первого практически мгновенно, что напрочь исключало возможность работы этого чата при помощи периодического опроса сервера скриптом на клиентской странице. Ну, или частота этого опроса должна быть настолько высокой, что любой сервер бы просто захлебнулся в этих запросах.</p><p>

И встал передо мной вопрос - как они это сделали? Как они обеспечили такую высокую скорость отдачи свежих данных? Ведь веб-сервер на то и сервер, что может лишь отвечать на запросы пользователя, но уж никак не самостоятельно инициировать запросы.
</p><p>
Непродолжительный поиск по интернетам дал мне ответ. И ответ этот "<strong>Long Polling</strong>", а встречается еще и другое название технологии - <strong>Comet</strong>.
</p><p>
Итак, как же это работает?
</p><p>
По сути, это все тот же старый добрый <em>AJAX</em>, и использование объекта <strong>XmlHttpRequest</strong>. С одной большой разницей, заключенной на серверной стороне. Разница состоит вот в чем. Клиент посылает <em>XHR</em>-запрос и длительное время ожидает ответа сервера. А "длительное время" отклика обеспечивает сам сервер, который не сразу отдает данные клиенту, а лишь только тогда, когда у него в очереди появляются свежие данные, то есть когда ему действительно есть что сказать.
</p><p>
Клиент, дождавшись ответа, обрабатывает его (например, отображает сообщение на странице), а затем, без промедления, снова запрашивает сервер. И снова ждет.
</p><p>
Если же подав запрос клиент так и не дождался ответа из-за таймаута, то он снова запрашивает сервер. А откуда этот таймаут? А просто серверу нам нечего ответить, вот он и не отдает клиенту результат запроса. Ждет. Но не дождавшись, разрывает соединение по таймауту. Такая вот несложная схема.
</p><p>
Это и называется <strong>Long Polling</strong>, то есть - <em>длительный опрос</em>.
</p><p>
Но от слов к делу. Сейчас мы изготовим серверную и клиентскую часть простого интернет-чата, построенного на описанной технологии. Мы подробно рассмотрим работу всего серверного и клиентского кода и даже в конце статьи получим ссылку на вполне работоспособный продукт. Сразу скажу, у него есть некоторые ограничения. Вы, например, не сможете его использовать в режиме сильной нагрузки, то есть наличии одновременно большого количества клиентов. В нем нет схемы очистки "потерянных" соединений. Это лишь работоспособный
учебный пример. Все недостающие аспекты кода предлагаю вам на самостоятельную доработку.
</p>
<p>Продолжение статьи <a href="http://easy4web.ru/?p=695">Реализация чата на ASP.NET с использованием Long Polling</a> вы можете прочитать на сайте <a href="http://easy4web.ru/">Веб-разработка? Это просто!</a></p>
<!-- " ' --></td>
</tr>
</table>]]></description>
<guid isPermaLink="false">1179838</guid>
<pubDate>Sat, 13 Mar 2010 21:31:30 MSK</pubDate>
</item>
</channel>
</rss>
