Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

В этом номере:


Информационный Канал Subscribe.Ru

.Net Собеседник #46

Содержание
  1. От автора
  2. Обзор новостей
  3. Использование ADOX применительно к MSAccess, c примерами на C#
  4. Время кода - У границ безопасного кода
  5. Форумы .Net на www.sql.ru

От автора

Здравствуйте, коллеги!

Итак, 4-й номер журнала практически готов. 6 статей, интервью, более полутора десятков новостей и обзоров компонет и их наборов - всё это можно будет прочесть в этом номере. В следующем выпуске рассылки будет дано его подробное содержание и ссылка на номер в электронном виде. А пока - сокращённые версии некоторых материалов, которые вошли в 4-й номер.

На этом всё- желаю интересного чтения.

{К содержанию}

Обзор новостей

  1. Компонет PractiX Schedule для .Net
    Первая версия компонента PractiX доступна по значительно сниженной цене, по сравнению с первоначально планировавшейся. Очень удачный компонент-календарь, гибкий, обладающий уникальными свойствами, прекрасным API, написанный полностью на C#.
  2. Catalyst File Transfer V4.5
    Компонент Catalyst File Transfer позволяет разработчикам легко интегрировать функциональность передачи и приёма файлов в приложения. Компонент реализует стандартные протоколы по отправке и скачиванию файлов через Сеть и корпоративные внутренние сети, так же может быть использован во многих языках, способных взаимодействовать с компонентами ActiveX.
  3. Вышла билиотека NMath Analysis
    NMath Analysis – библиотека классов .NET, содержащая функции и структуры данных для оптимизации функций, включая минимизацию одномерных и многомерных функций, линейное программирование методом симплексовметод наименьших квадратов и т.д.
  4. Вышла библиотека VintaSoftTwain.NET 1.3
    Библиотека VintaSoftTwain.NET Library – чистая .NET библиотека, которая позволяет контролировать работу сканнеров, камер и других устройст, поддерживающих интерфейс TWAIN.
  5. Aspose.Pdf 2.5
    Aspose.Pdf является компонентом для создания отчётов на платформе .Net, а также позволяющий вам создавать отчёты в формате Pdf без задействования продуктов фирмы Adobe.
  6. У Oracle появились новые .NET-инструменты
    Oracle приняла участие в программе Microsoft Visual Studio Industry Partner (VSIP) в мае, а теперь объявила о выходе Oracle Developer Tools для Visual Studio .NET, бесплатного плагина, позволяющего разработчикам, использующим Microsoft Visual Studio .NET разрабатывать и устанавливать приложения, использующие Oracle Database 10g на Microsoft Windows. Этот плагин интегрирует базу данных Oracle 10g и Visual Studio .NET и укрепляет намерения Oracle соответствовать требованиям общества разработчиков под Windows.
  7. Microsoft поддтверждает заявленые сроки выхода SQL Server 2005 и Visual Studio 2005
    В следующем месяце Microsoft намерена выпустить предварительные версии пакета для разработки приложений и базы данных, дата релиза которой неоднократно переносилась. По словам Прашанта Шридхарана, ведущего менеджера подразделения разработки ПО Microsoft, компания планирует представить новые продукты на Конференции профессиональных разработчиков (Professional Developers Conference), которая будет проходить 12 сентября в Лос-Анджелесе. Шридхаран также добавил, что конечные версии пакетов будут доступны пользователям не позднее 7 ноября.

{К содержанию}

Статья номера

Использование ADOX применительно к MSAccess, c примерами на C#

ЯЗЫК: C#
Автор статьи: Н.Зимин, полную версию статьи читайте в №4 журнала "Алгоритм"
 

Введение

Полное название ADOX — Microsoft ActiveX Data Objects Extensions for Data Definition Language and Security. Другими словами, ADOX — это COM-библиотека, являющаяся дополнением к библиотеке ADO и предназначенная для управления структурой и безопасностью базы. ADOX позволяет как получить информацию об объектах, так и управлять ими — создавать, изменять и удалять. Объекты, доступные ADOX — это таблицы (Tables), их поля (Columns), ключи (Keys) и индексы (Indexes), процедуры (Procedures) и вьюшки (Views), а также пользователи (Users) и группы (Groups). ADOX не доступны такие объекты MS Access как: формы, отчеты, страницы, макросы и модули. Данная статья ориентирована на использование ADOX для баз формата MDB. Вообще говоря, ADOX предназначен для работы не только с базами MS Access, но наиболее полно поддержка ADOX реализована в OLE DB Provider for MS Jet.

Подробнее см. Provider Support for ADOX (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/adconprovidersupportforadox.asp ). См. также: Описание ADOX в MSDN (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/admscadoddloverview.asp ), CodeGuru: ADOX in Detail(http://www.codeguru.com/Cpp/data/mfc_database/ado/article.php/c4343 ), ADO Provider Properties and Settings (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnacc2k/html/adoproperties.asp ).

Соединение с базой

Соединение с базой устанавливается либо в результате создания базы вызовом Catalog.Create (см. ниже), либо «вручную» — для существующей базы. В обоих случаях используется одна и та же строка соединения (connection string).

Строка соединения

public static string GetConnectionString(
        string ADatabasePath, string AShareMode, string APassword) {
        
    StringBuilder connText = new StringBuilder();
    connText.Append("Provider=Microsoft.Jet.OLEDB.4.0;");
    connText.Append("Data Source=\"").Append(ADatabasePath).Append("\";");
    connText.Append("Mode=").Append(AShareMode).Append(";");
    if (APassword != string.Empty)
        connText.Append("Jet OLEDB:Database Password=\"").Append(APassword).Append("\";");
    connText.Append("Jet OLEDB:Engine Type=5;");
    connText.Append("Jet OLEDB:Encrypt Database=True;");
    connText.Append("User ID=\"Admin\";");
    
    return connText.ToString();
}

Про Provider-Specific Connection Parameters см.: Microsoft OLE DB Provider for Microsoft Jet (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdrefjetprovspec.asp ) См. также: ADO Connection Strings (http://www.codeproject.com/database/connectionstrings.asp ), www.connectionstrings.com.  

Открытие/закрытие соединения

Здесь и далее предполагается, что в проекте уже установлены ссылки на ADO и ADOX: в Solution Explorer правой кнопкой на References, пункт Add Reference, вкладка COM, выбрать строку Microsoft ADO Ext. 2.7 for DDL and Security, нажать Select, выбрать строку Microsoft ActiveX Data Objects 2.8 Library, нажать Select, затем OK. Таким образом, c объектами ADO и ADOX мы будем использовать через раннее связывание. Раннее связывание выбрано с целью сделать код примеров более нагладным. Работа через позднее связывание, конечно, также возможна. Пусть у нас в каком-либо модуле будут две ссылки:

static ADODB.Connection g_adodbConnection; 
static ADOX.Catalog g_adoxCatalog;

Собственно открытие соединения:

public static ADOX.Catalog OpenAdoxConnection(string connectionString) { 
    try { 
        g_adodbConnection = new ADODB.ConnectionClass();
        g_adodbConnection.Open(connectionString, nullnull, 0);
        g_adoxCatalog = new ADOX.CatalogClass(); 
        g_adoxCatalog.ActiveConnection = g_adodbConnection; 
    } catch (Exception ex) { 
        throw new Exception("Failed to open connection", ex); 
    } 
    return g_adoxCatalog; 
}

Закрытие соединения:

public static void CloseAdoxConnection() {
    try {
        if (g_adodbConnection != null) {
            g_adoxCatalog = null;
            g_adodbConnection.Close();
            g_adodbConnection = null;
        }
    }
    catch {  //suppress exceptions
    }
}

Сжатие/восстановление базы (Compact/Repair)

В БД Access при операциях удаления соответствующие строки, таблицы и другие объекты на самом деле НЕ удаляются, а лишь помечаются как удаленные. В результате объем файла БД монотонно растет. См. также: FAQ / MS Access / Сжатие БД [SQL.Ru] (http://www.sql.ru/faq/faq_topic.aspx?fid=155 ).

Оценка объема, высвобождаемого при сжатии

При наличии открытого ADODB-соединения всегда можно сказать — нужно ли сжимать базу. Свойство «Jet OLEDB:Compact Reclaimed Space Amount» соединения дает количество байт, высвобождаемых при сжатии.

public static int GetCompactReclaimedSpaceAmount(string connectionString) {
// Открытие соединения
    ADODB.Connection connobj = new ADODB.ConnectionClass();
    connobj.Open(connectionString, nullnull, 0);
// Получение значения свойства "Jet OLEDB:Compact Reclaimed Space Amount"
    int value = 0;
    try {
        value = (int) connobj.Properties["Jet OLEDB:Compact Reclaimed Space Amount"].Value;
    } finally {
        connobj.Close();
    }
    return value;
}

Собственно сжатие

Из ADOX функция сжатия/восстановления недоступна, но эту операцию можно выполнить с помощью библиотеки Jet and Replication Objects (JRO). Перед выполнением сжатия все соединения с базой должны быть закрыты.

public static void CompactDatabase(string ADatabasePath, string ADatabasePassword) {
    string TempFileName = Path.GetTempFileName();
    if (File.Exists(TempFileName))
        File.Delete(TempFileName);  // Удаляем файл нулевой длины, созданный Path.GetTempFileName() 
    try { 
// Сжатие из файла ADatabasePath в файл TempFileName
        CompactDatabaseJro(
            GetCompactConnectionString(ADatabasePath, ADatabasePassword),
            GetCompactConnectionString(TempFileName, ADatabasePassword)); 
        File.Copy(TempFileName, ADatabasePath, true); 
    } finally { 
// Удаляем временный файл
        if (File.Exists(TempFileName))
            File.Delete(TempFileName); 
    }        
} private static string GetCompactConnectionString(string databasePath, string password) { 
    StringBuilder connText = new StringBuilder(); 
    connText.Append("Provider=Microsoft.Jet.OLEDB.4.0;"); 
    connText.Append("Data Source=\"").Append(databasePath).Append("\";"); 
    if (Common.g_Password != string.Empty)
        connText.Append("Jet OLEDB:Database Password=\"").Append(password).Append("\";");
    connText.Append("Jet OLEDB:Engine Type=5;"); 
    connText.Append("Jet OLEDB:Encrypt Database=True;"); 
    return connText.ToString(); 
}

private static void CompactDatabaseJro(string SrcConnectionString, string DestConnectionString) {
    Type typeJROJetEngine = Type.GetTypeFromProgID("JRO.JetEngine");
    object jro = Activator.CreateInstance(typeJROJetEngine);
    object[] parameter = new object[2];
    parameter[0] = SrcConnectionString;
    parameter[1] = DestConnectionString;
    typeJROJetEngine.InvokeMember("CompactDatabase", BindingFlags.InvokeMethod, null, jro, parameter);
    jro = null;
}

Заключение

В большинстве случаев ADOX может заменить обычные DDL-операции, привычные для SQL. Это тем более актуально для MS Access, в котором нет родной поддержки работы с SQL-скриптами. Сфера применения ADOX — исследование и изменение структуры базы. И, несмотря на ряд ограничений, ADOX прекрасно справляется с этими задачами. В качестве иллюстрации к данной статье предлагается пример ADOX Analyzer

{К содержанию}

Время кода

У границ безопасного кода

ЯЗЫК: C#
Автор статьи: Э.Гюннерсон
, полную версию статьи читайте в №4 журнала "Алгоритм"

Вступление

В мире C++, использование указателей является составной частью языка. Это придаёт C++ огромную мощь и гибкость, что, однако, является как его силой, так и его слабостью. Силой это является потому, что C++ даёт вам много свободы для создания именно того, что вам нужно, но эта же свобода также является порождением множества ошибок в программном обеспечении.
Подход Java, с другой стороны, таков, что с указателями сплошные проблемы, поэтому они вообще недоступны программисту. Это значит, что вам не придётся иметь дело с ошибками, присущими программированию с использованием указателей. К сожалению, вы одновременно не сможете использовать преимущества указателей.
Позиция C# в отношении указателей находится где-то между позицией C++ и Java. Для подавляющего большинства кода, который пишут люди, недостатки указателей перевешивают их преимущества, именно поэтому в C# недоступно использование указателей в "нормальном" коде. С прагматической точки зрения, однако, бывают случаи, когда указатели очень полезны, так что в C# есть способ их использования.
Такой подход предоставляет нам, программистам, лучшее из двух миров – модель безопасности Java совместно с гибкостью модели C++ - при необходимости. Ситуации, в которых эта гибкость необходима, могут быть сгруппированы в три категории:

1. Производительность
2. Взаимодействие с существующими двоичными структурами
3. Улучшенное взаимодействие с COM- или родными библиотеками

Прогуливаемся по массиву

В моём приложении критически важна максимальная скорость суммирования чисел в массиве, так что я собираюсь исследовать несколько методов для исполнения этой операции. Первым делом был испробован foreach:

static int AddArrayForeach(int[] numbers)
{
   int result = 0;
   for (int it = 0; it < Iterations; it++)
   {
      foreach (int i in numbers)
      {
         result += i;
      }
   }
   return result;
}

Внутренний цикл явно использует foreach для перебора всех элементов массива и добавляет значение к результату. Если бы дело касалось реализации функции, то на этом можно было бы и закончить. Но поскольку мы собираемся провести тесты, то мы должны проделать эту операцию столько раз, чтобы общее время её выполнения было более одной секунды. Таким образом, foreach встроен во внешний цикл, практически повторяя весь процесс указанное число раз.
Время измеряется классом-счётчиком, использующим счётчики производительности Windows NT® для точного измерения времени. При работе над производительностью очень важно измерить эту самую производительность, над которой мы и работаем.
Код измерения производительности:

Counter counter = new Counter();
int result;
counter.Clear();
counter.Start();
result = AddArrayForeach(numbers);
counter.Stop();
Console.WriteLine("Foreach {0}, {1} seconds", result, counter.Seconds);

Наша первая реализация произошла (100 итераций за массив с 1,000,000 элементов) за 1.84 секунды.
Зная, как работает foreach, можно предположить, что мы теряем в производительности из-за того, что не сами реализовали цикл. Попробуем слегка исправленную версию:

static int AddArrayFor(int[] numbers)
{
   int result = 0;
   for (int it = 0; it < Iterations; it++)
   {
      for (int index = 0; index < numbers.Length; index++)
      {
         result += numbers[index];
      }
   }
   return result;
}

В этом примере мы используем доступ к элементам массива по индексу.
Этот подход занимает 1.80 секунды, что на 3% быстрее предыдущего – не очень-то удачное улучшение.
Теперь перепишем эту же функцию с использованием небезопасного кода. Для этого нужно знать, каким образом реализованы массивы в общей БВВ (Common Language Runtime - CLR).
Массив в CLR – один большой кусок памяти, достаточный для хранения всех элементов. В нашем примере мы имеем дело с массивом из n целых, так что мы имеем кусок памяти с хранящейся в ней n целых. При использовании синтаксиса индексирования массива, класс максима определяет какой элемент нам нужен, берёт стартовый адрес массива в памяти и добавляет к нему индекс искомого элемента. Это даёт нам адрес указанного элемента, а его значение мы можем взять по этому адресу.
Вот так работает класс массива, если мы передаём ему правильный индекс. Поскольку класс массива должен быть безопасным, то он проверяет переданный индекс, что слегка замедляет его работу.
Наша версия использования небезопасного кода должна работать быстрее, поскольку мы не будем выполнять такую проверку. Поскольку мы работаем самостоятельно, необходимо быть осторожным и не допустить ошибок, которые сделают работу программы нестабильной. Вот и код:

unsafe static int AddArrayUnsafe(int[] numbers)
{
   int result = 0;
   for (int it = 0; it < Iterations; it++)
   {
      fixed (int* pNumber = numbers)                    // 1
      {
         int* pCurrent = pNumber;                    // 2
         int* pLimit = pNumber + numbers.Length;     // 3
         while (pCurrent < pLimit)                   // 4
         {
            result += *pCurrent;                  // 5
            pCurrent++;                           // 6
         }
      }
   }
return result;
}

При использовании такого подхода мы получим время в 1.55 секунды, что на 14% быстрее версии, использующей цикл. В итоге можно сказать, что мы взяли код, который легко читаем и легко изменяем и заменили его на более сложный. По ходу дела мы должны убедиться, что код запускается как полностью доверенная сборка.
Всё это мы делаем ради 14% прироста быстродействия. Стоит ли оно того?
Ответ на этот вопрос зависит от типа вашего приложения, но в целом ответ скорее должен быть "нет, не стоит". Для подавляющего большинства приложений вы получите гораздо лучший результат, написав простой код и затем использовуя своё время для улучшения алгоритмов. Если же прирост в 14% кажется вам существенным, то тогда конечно нужно обратиться к небезопасному коду.


{К содержанию}

Форумы .Net - вопросы оставшиеся без ответа

Проблема с кодировкой при загрузке таблиц Paradox
@RETURN_VALUE
Ошибка компиляции при создания SQLConnection (VS7)
DataBindings при разрешенном значении поля Null
Свойства
кто как выкручивается
Сохранение Crystal – отчетов в CRM автоматически
Сортировка узлов в TreeNode(NET 2.0)?
Пользовательские коллекции

На этом сорок шестой выпуск .Net Собеседника закончен.
До следующего номера.


Чужа Виталий Ф. aka hDrummer, MCAD, MCDBA, MCP
hdrummer ухо gmail точка ru - жду ваши предложения и замечания.



Subscribe.Ru
Поддержка подписчиков
Другие рассылки этой тематики
Другие рассылки этого автора
Подписан адрес:
Код этой рассылки: comp.soft.prog.dotnetgrains
Отписаться
Вспомнить пароль

В избранное