Создайте компактный файл sql server в папке appdata

Я разрабатываю простую часть программного обеспечения, в которой сначала используется код Entity Framework и sql server compact 4. На данный момент эта настройка работает. Entity framework создает компактный файл sql-сервера, если он еще не существует. Путь к базе данных определяется из строки соединения, которая хранится внутри файла app.config. Он создается следующим образом:

<connectionStrings>
  <add name="DataContext" 
       connectionString="Data source=Database.sdf;"
       providerName="System.Data.SqlServerCe.4.0"/>
</connectionStrings>

Однако я хочу разместить базу данных в папке в текущей папке Application Application (папка C:\Users\User\AppData\Roaming на моей машине win7). Я попытался установить источник данных в строке соединения на что-то вроде% APPDATA%\Database.sdf, но это не сработает, я получаю исключение "Незаконные символы в пути".

Я хочу придерживаться метода connectionstring, потому что я бы хотел использовать другую базу данных для своих модульных тестов, чем с моим фактическим приложением. Таким образом, легко изменить базу данных, поместив файл app.config в корень проекта.

Может ли кто-нибудь направить меня в правильном направлении?

Ответ 1

Используйте ниже:

AppDomain.CurrentDomain.SetData("DataDirectory", Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData));

<connectionStrings>
  <add name="DataContext" 
       connectionString="Data source=|DataDirectory|Database.sdf;"
       providerName="System.Data.SqlServerCe.4.0"/>
</connectionStrings>

Ответ 2

    connectionString="Data source=Database.sdf;"

Это говорит вашему приложению искать Database.sdf в текущем рабочем каталоге приложений; который может быть где угодно и может не поддаваться записи. Вам нужно посмотреть местоположение, которое вы указали:

    connectionString="Data source=|DataDirectory|Database.sdf;"

ADO.NET ищет символы канала в строках соединения и расширяет их до значения свойства этого имени в домене приложений. Итак, каково значение свойства DataDirectory? Предполагается, что он будет установлен любым развертыванием вашего приложения:

  • .MSI установщики устанавливают его в папку установки приложения. Если вы разрешите пользователю выбирать папку установки, они также выбирают DataDirectory. Вот почему вы всегда должны использовать |DataDirectory| и никогда не закодированный путь.
  • ClickOnce определяет специальную папку данных в вашем проекте.
  • Веб-приложения используют папку App_Data.
  • Отладчик Visual Studio использует папку отладки.

Все файлы Visual Studio в вашем проекте с свойством "копировать в выходной каталог" будут скопированы в DataDirectory. В большинстве случаев DataDirectory будет доступной только для чтения. Это нормально, если ваши данные доступны только для чтения, но если вы хотите записать их, вам придется скопировать данные в место для записи. Вероятно, лучшим местом является Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData)). Существует несколько способов сделать это:

  • Если вы создаете пустой новый файл данных, просто используйте стандартные стандарты API CREATE DATABASE или new SqlCeConnection() или что-то еще.
  • Если вы хотите начать с предварительно заполненной базы данных семян или стартеров, включите базу данных семян в свой проект. В процессе запуска приложения проверьте, существует ли база данных в папке SpecialFolder.ApplicationData и, если нет, скопируйте ее там.

Если вы ищете в Интернете образец кода при создании локальной базы данных, вы столкнетесь с множеством плохих советов. Не выполняйте следующее:

new SqlCeConnection(@"Data source=c:\users\me\myApp\Database.sdf;");  // Do NOT do this!

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

using (var conn = new SqlCeConnection(@"Data source=|DataDirectory|Database.sdf;"))
{
    conn.Open();
    // No No No! This throws an Access Exception for Standard users,
    // and gets deleted when you repair the app!
    var cmd = conn.CreateCommand("INSERT INTO Table (column1, column2) VALUES (@p1, @p2)");
    ...
}

Не пытайтесь изменить данные в DataDirectory. Этот каталог не всегда может быть изменен не только пользователями, но и не установлен пользователем. При восстановлении или удалении приложения удаляются все данные пользователей; пользователям это не нравится. Вместо этого скопируйте установленные данные в папку, доступную для записи пользователем, и внесите все изменения в копию.

AppDomain.CurrentDomain.SetData("DataDirectory",
    // Wrong, this overwrites where the user installed your app!
    Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData));

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

Я также препятствую сохранению данных в Environment.SpecialFolder.CommonApplicationData. Это может быть недоступно для записи пользователями, и, если не существует очень веской причины, всем пользователям должно быть разрешено изменять данные других пользователей, каждый пользователь должен иметь свою собственную базу данных.