1. 程式人生 > 程式設計 >c# DataDirectory的用法

c# DataDirectory的用法

筆者在使用Entity Framework中的Scaffolding機制自動建立拓展名為mdf的資料庫及表單時,遇到如下的錯誤:

A file activation error occurred.
The physical file name '\\MusicDBContext.mdf' may be incorrect.
Diagnose and correct additional errors,and retry the operation.
CREATE DATABASE failed. Some file names listed could not be created.
Check related errors.

首先回顧一下建立這個程式的步驟:

1、建立一個Console控制檯應用程式,程式集名稱及名稱空間為ConsoleApp;

2、使用程式包控制檯管理器將Entity Framework包含到此程式中,程式碼如下:

PM> install-package Entity Framework

3、在App.Config檔案中將以下內容插入到configuration節點:

<connectionStrings>
  <add name="MusicDBContext"
    connectionString="Data Source=(LocalDb)\MSSQLLocalDB;
     Initial Catalog=MusicDBContext;Integrated Security=SSPI;
     AttachDBFilename=|DataDirectory|\MusicDBContext.mdf"
    providerName="System.Data.SqlClient" />
</connectionStrings>

4、在控制檯編寫以下程式碼:

using System;
using System.Linq;
using System.Data.Entity;
namespace ConsoleApp
{
  class Program
  {
    static void Main(string[] args)
    {
      try
      {
        MusicDbContext db = new MusicDbContext();
        Music music = new Music { Title = "Far Away From Home",ReleaseDate = DateTime.Now };
        db.Musics.Add(music);
        db.SaveChanges();
        db.Musics.ToList().ForEach(x => Console.WriteLine($"{x.ID},{x.Title},{x.ReleaseDate}"));
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
        if(ex.InnerException != null)
        {
          Console.WriteLine(ex.InnerException.Message);
        }
      }
      Console.ReadKey();
    }
  }
  public class Music
  {
    public int ID { get; set; }
    public string Title { get; set; }
    public DateTime ReleaseDate { set; get; }
  }
  public class MusicDbContext : DbContext
  {
    public MusicDbContext() : base("MusicDBContext") { }
    public DbSet<Music> Musics { set; get; }
  }
}

5、執行此程式,發現程式不能按自己想要的結果執行,出現在最前面出現的錯誤。

通過查看出錯的資訊,發現

AttachDBFilename=|DataDirectory|\MusicDBContext.mdf

有問題,而這又是沒有問題的,這到底是怎麼回事?為什麼會出現錯誤?

於是,通過MSDN查詢相關資料,通過以下方法獲得DataDirectory指定的路徑是什麼:

object path = AppDomain.CurrentDomain.GetData("DataDirectory");

執行此行程式碼,發現path居然是null!!!什麼?一般控制檯或者Windows Form程式根據是Debug還是Release決定DataDirectory的初始化路徑為Bebug資料夾還是Release資料夾嗎?

這個錯了。

如果原先的Bebug資料夾或Release資料夾存在資料庫檔案,使用類似"AttachDBFilename=|DataDirectory|\MusicDBContext.mdf"的寫法是沒有問題的,

即使path = null,它也知道是在Bebug資料夾或Release資料夾下。

如果原先的Bebug資料夾或Release資料夾不存在資料庫檔案,上面的寫法就有問題,也就會出現最開始出現的那種錯誤。

那麼,我們該如何解決呢?細心的人可以發現,既然可以使用AppDomain.CurrentDomain.GetData來獲得DataDirectory指定的路徑,

那及可以使用AppDomain.CurrentDomain.SetData來指定DataDirectory的初始化路徑,程式碼如下:

AppDomain.CurrentDomain.SetData("DataDirectory",Environment.CurrentDirectory);

通過以上的方法,就可以解決最開始前面的問題。

通過以上的介紹,最終的程式碼修改如下:

using System;
using System.Linq;
using System.IO;
using System.Data.Entity;

namespace ConsoleApp
{
  class Program
  {
    static void Main(string[] args)
    {
      string dbPath = Environment.CurrentDirectory + @"\MusicDBContext.mdf";
      if(!File.Exists(dbPath))
      {
        AppDomain.CurrentDomain.SetData("DataDirectory",Environment.CurrentDirectory);
      }
      try
      {
        MusicDbContext db = new MusicDbContext();
        Music music = new Music { Title = "Far Away From Home",{x.ReleaseDate}"));
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
        if(ex.InnerException != null)
        {
          Console.WriteLine(ex.InnerException.Message);
        }
      }
      Console.ReadKey();
    }
  }

  public class Music
  {
    public int ID { get; set; }
    public string Title { get; set; }
    public DateTime ReleaseDate { set; get; }

  }

  public class MusicDbContext : DbContext
  {
    public MusicDbContext() : base("MusicDBContext") { }
    public DbSet<Music> Musics { set; get; }
  }
}

程式就可以正常運行了。

注:

1)AttachDBFilename=|DataDirectory|\MusicDBContext.mdf

其中的“\”可以省略掉,即為:AttachDBFilename=|DataDirectory|MusicDBContext.mdf

2)如果是ASP.NET程式,DataDirectory的初始化目錄為App_Data。

3)關於更多的|DataDirectory|知識,請參考如下:

https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/ef/connection-strings

https://stackoverflow.com/questions/1409358/ado-net-datadirectory-where-is-this-documented/1409378#1409378

https://stackoverflow.com/questions/51948028/a-file-activation-error-occurred-when-using-entity-framework

以上就是c# DataDirectory的用法的詳細內容,更多關於c# DataDirectory的資料請關注我們其它相關文章!