LINQ to SQL и SQL Server Compact Edition

В последнее время на различных мероприятиях для разработчиков мы часто слышим много новых и модных красивых слов. К таковым, например, относятся LINQ и SQL Server Compact Edition.

Как вы уже знаете, LINQ - это типизированный язык запросов к любым источникам данных. Используя LINQ мы строим строго типизированный запрос, который проверяется на этапе компиляции, получаем строго типизированные результаты и т.д.; при этом эти запросы мы строим единообразно будь источником данных у нас SQL Server, либо коллекция объектов.

SQL Server Compact Edition (SSCE) — тоже многообещающая технология. Фактически это in-proc мини-engine баз данных, который поддерживает T-SQL, не требует установки и может работать как на desktop-, так и на mobile-приложениях.

Обе технологии, несомненно интересные и многообещающие. Так, например, все очень хорошо понимают сколько времени можно сэкономить на построении уровня данных, используя LINQ. С другой стороны для небольших приложений использование SSCE позволяет сэкономить много времени при развертывании.

Конечно, напрашивается решение использовать эти две технологии совместно, но не тут то было :) При попытке добавить в проект "LINQ to SQL Classes" (.dbml), и замапить их на источник данных SSCE получаем ненавязчивое сообщение.

Нда.. не очень, конечно, приятно. Но выход есть - использование утилиты SqlMetal. Эта утилита представляет собой консольное приложение, которое по существующей схеме данных позволяет сгенерировать dbml-файл. Собственно, утилита работать может как с обычным SQL Server, так и с SSCE, что нам и нужно. В случае с SSCE использовать ее очень просто:

SqlMetal /dbml:northwind.dbml northwind.sdf

Т.е. мы просто указываем пути к файлу данных SSCE (.sdf) и путь к файлу с результатами. На выходе получаем .dbml-файл, который теперь можем запросто добавить в проект и работать с SSCE уже через LINQ to SQL. В конструкторе context-класса нас попросят указать connection string следующего вида: "Data Source=.\\Northwind.sdf"

Однако, на этом наши проблемы не закончатся. При первом запуске может возникнуть ошибка:

Cannot open "Northwind.sdf". Provider 'System.Data.SqlServerCe.3.5' not installed.1

Все дело в том, что в корневом конфигурационном файле не прописан провайдер для SSCE, поэтому в config-файле своего приложения сделаем это:

<configuration>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SqlServerCe.3.5" /> 
      <add name="Microsoft SQL Server Compact Data Provider"
           invariant="System.Data.SqlServerCe.3.5"
           description=".NET Framework Data Provider for Microsoft SQL Server Compact"
           type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=3.5.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" /> 
    </DbProviderFactories>
  </system.data> 
</configuration>

Собственно, эти данные прописываются в machine.config автоматически, если мы устанавливаем SSCE Windows Installer-ом (а не через x-copy).

Если у вас Windows 32-bit, то на этом шаге у вас все должно заработать. Однако мне повезло меньше - у меня Windows 64-bit, из-за чего проблемы продолжились. Насколько мне удалось найти информацию на эту тему я сделал вывод - на данный момент SSCE работает только в 32-разрядном режиме. Поэтому проблему можно решить определив, что проект компилируется для x86 (в Configuration Manager).

Другой, более изощренный способ - использовать утилиту "corflags.exe", которая позволяет включить 32-битный режим уже для готовой сборки:

corflags ...\bin\Debug\consoleapplication1.exe /32BIT+

Вывод. Использовать LINQ2SQL и SSCE можно, но не без проблем :)

Updated: поддержка x64 будет в SSCE 3.5 SP1. Подробности тут. Так что ждем SP1 с еще большим нетерпением :)