Создание файла SQL server compact в папке appdata

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

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

однако я хочу поместить базу данных в папку в папке данных приложения текущего пользователя (the C:UsersUserAppDataRoaming папка на моей машине win7). Я попытался установить источник данных connectionstring на что-то вроде %APPDATA%Database.sdf, но это не работает, я получаю исключение "незаконные символы в пути".

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

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

2 ответов


использовать ниже:

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>

    connectionString="Data source=Database.sdf;"

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

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

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

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

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

  • если вы создаете пустой новый файл данных, просто используйте стандарт вашего API CREATE DATABASE или new SqlCeConnection() или что угодно.
  • если вы хотите начать с предварительно заполненной базы данных seed или starter, включите базу данных seed в свой проект . При запуске приложения проверьте, существует ли база данных в 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. Это не может быть доступным для записи пользователями, и если нет очень веской причины, по которой всем пользователям должно быть разрешено изменять данные других пользователей, каждый пользователь должен иметь свою собственную базу данных.