当前位置: 首页 > 编程笔记 >

c# DataDirectory的用法

刘弘新
2023-03-14
本文向大家介绍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", 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的资料请关注小牛知识库其它相关文章!

 类似资料:
  • 问题内容: 这是关于带有Visual Studio 2012 Ultimate和SQL Server Express 2012的ConnectionStrings / ASP.NET MVC。 在这里跟进本教程:http : //www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/intro-to- aspnet-mvc

  • 问题内容: 我正在使用本地数据库,由于某种原因,当我使用时,添加/删除时数据库不会更新 但是, 如果我使用以下目录,它确实可以工作 有人知道为什么吗? 问题答案: 变量具有基于OS的.NET Framework设置的值。 我对此做了一个快速实验。 当我运行上面的代码时,它什么也没显示。调试后,我发现该变量具有值。 然后,我尝试使用它来创建数据库连接并打开它。 此代码失败,并出现以下错误。 尝试为文

  • 本文向大家介绍C++中extern "C"的用法,包括了C++中extern "C"的用法的使用技巧和注意事项,需要的朋友参考一下 学习过C++的人都知道,extern关键字可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。这里起到的是声明作用范围的用处。另外,extern还可以与”C”连用,作为链接指示。本文就此进行实例说明如下:

  • 本文向大家介绍Python使用ctypes调用C/C++的方法,包括了Python使用ctypes调用C/C++的方法的使用技巧和注意事项,需要的朋友参考一下 python使用ctypes调用C/C++ 1. ctpes介绍 ctypes is a foreign function library for Python. It provides C compatible data types, a

  • 本文向大家介绍C/C++中*和&的用法详解,包括了C/C++中*和&的用法详解的使用技巧和注意事项,需要的朋友参考一下 C++中&和*的用法一直是非常让人头疼的难点,课本博客上讲这些知识点一般都是分开讲其用法的,没有详细的总结,导致我在这方面的知识结构格外混乱,在网上找到了一篇英文文章简单总结了这两个符号的一些用法,都是一些比较基础的知识,我比较关心的函数指针,指针函数等都没有涉及到,今后有时间把

  • 本文向大家介绍C++调用C#的DLL实现方法,包括了C++调用C#的DLL实现方法的使用技巧和注意事项,需要的朋友参考一下 SwfDotNet是C#编写的,这是个特别好的读写Swf文件的库。本文讲述了在C++项目中,怎么让C++调用C#的DLL动态链接库文件。 具体的实现步骤如下: 一、创建C# DLL,需要指定应用类型为“类库”,代码: 二、C++客户程序,是个控制台应用,代码: 三、这里有几点