c# DataDirectory的用法

所属分类: 软件编程 / C#教程 阅读数: 128
收藏 0 赞 0 分享

笔者在使用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", 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

     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的资料请关注脚本之家其它相关文章!

更多精彩内容其他人还在看

C#实现写系统日志的方法

这篇文章主要介绍了C#实现写系统日志的方法,涉及C#针对系统日志的创建、写入及删除等技巧,非常具有实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C#编程实现自定义热键的方法

这篇文章主要介绍了C#编程实现自定义热键的方法,涉及C#键盘按键设置的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C#实现读取被进程占用的文件实现方法

这篇文章主要介绍了C#实现读取被进程占用的文件实现方法,涉及C#进程操作及文件读取的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C#获取任务栏显示进程的方法

这篇文章主要介绍了C#获取任务栏显示进程的方法,涉及C#针对进程操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C#调用dos窗口获取相关信息的方法

这篇文章主要介绍了C#调用dos窗口获取相关信息的方法,涉及C#调用dos窗口及进程操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C#通过Semaphore类控制线程队列的方法

这篇文章主要介绍了C#通过Semaphore类控制线程队列的方法,涉及Semaphore类操作线程队列的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C#使用Dispose模式实现手动对资源的释放

这篇文章主要介绍了C#使用Dispose模式实现手动对资源的释放,涉及C#采用Dispose模式操作资源的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C#动态创建button的方法

这篇文章主要介绍了C#动态创建button的方法,涉及C#按钮属性动态设置的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C#编程获取资源文件中图片的方法

这篇文章主要介绍了C#编程获取资源文件中图片的方法,涉及C#针对项目中资源文件操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

WinForm实现窗体最大化并遮盖任务栏的方法

这篇文章主要介绍了WinForm实现窗体最大化并遮盖任务栏的方法,涉及C#实现WinForm窗体全屏显示的实现及调用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多