笔者在使用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.
首先回顾一下建立这个程序的步骤:ide
一、建立一个Console控制台应用程序,程序集名称及命名空间为ConsoleApp;this
二、使用程序包控制台管理器将Entity Framework包含到此程序中,代码以下:spa
PM> install-package Entity Framework
三、在App.Config文件中将如下内容插入到configuration节点:code
<connectionStrings> <add name="MusicDBContext" connectionString="Data Source=(LocalDb)\MSSQLLocalDB; Initial Catalog=MusicDBContext;Integrated Security=SSPI; AttachDBFilename=|DataDirectory|\MusicDBContext.mdf" providerName="System.Data.SqlClient" /> </connectionStrings>
四、在控制台编写如下代码:orm
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; } } }
五、运行此程序,发现程序不能按本身想要的结果运行,出如今最前面出现的错误。blog
经过查看出错的信息,发现get
AttachDBFilename=|DataDirectory|\MusicDBContext.mdf
有问题,而这又是没有问题的,这究竟是怎么回事?为何会出现错误?string
因而,经过MSDN查找相关资料,经过如下方法得到DataDirectory指定的路径是什么:it
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", 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; } } }
程序就能够正常运行了。
注:
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