c# DataDirectory的用法
作者:cnxy 发布时间:2021-07-30 14:36:22
笔者在使用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
来源:https://www.cnblogs.com/cncc/p/9515991.html


猜你喜欢
- 本文实例讲述了Java中对象的比较操作。分享给大家供大家参考,具体如下:一 点睛在Java中,有两种方式可用于对象间的比较:利用"
- 一、前言拖拽(Drag&Drop),属于是极其常用的基础功能。无论是在系统上、应用上、还是在网页上,拖拽随处可见。同时拖拽时的鼠标效
- Spring的主要特性包括IOC和DI,其中DI是IOC的基础。在以前的Spring使用过程中大部分都是使用XML配置文件显式配置sprin
- 本篇文章主要内容来自于Android Doc,我翻译之后又做了些加工,英文好的朋友也可以直接去读原文。http://developer.an
- 所需引入Jar包:jms-1.1.jaractivemq-all-5.15.0.jar生产者package com.mousewheel.d
- 1: .net framework 由两个部分组成:CLR 和 FCL。2:在CLR中,所有错误都是通过异常来报告的。3:智能感知功能主要是
- 我在做毕设的时候采用shiro进行登录认证和权限管理的实现。其中需求涉及使用三个角色分别是:学生、教师、管理员。现在要三者实现分开登录。即需
- 本文实例讲述了C#编程获取各种电脑硬件信息的方法。分享给大家供大家参考,具体如下:获取CPU编号:ManagementClass mc =
- 1.问题描述在一个目录及子目录下查找 TXT或Java文件,从中搜索所有“对象”字样的行。在D盘中的所有文件中搜索含有“对象”的行。2.解题
- 首先给大家展示下效果图,感觉还不错,请继续往下阅读:下拉刷新: 上划加载 &n
- 本文实例为大家分享了Android实现注册界面的具体代码,供大家参考,具体内容如下LinearLayout 控制布局TextView 用于显
- 一、概述Overview - LINQ to XML | Microsoft 官方文档LINQ to XMLLINQ to XML 是一种启
- 定义JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动
- 建造者模式概述建造者模式(Builder Pattern)属于创建型模式。它是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同
- 在面向对象设计原则中,要求"要依赖于抽象,不要依赖于具体", 这句话有很多人搞不懂。在这里谈谈我自己的理解。首先看看以下
- 一、JavaMail API简介 JavaMail API是读取、撰写、发送电子信息的可选包。我们可用它来建立如Eudora、Foxmail
- 前言Handler,可谓是面试题中的一个霸主了。在我《面试回忆录》中,几乎没有哪家公司,在面试的时候是不问这个问题的。简单一点,问问使用流程
- 概述LinearLayout是线性布局组件,放置在其中的组件按列或者按行(就是垂直或者水平)的方式排序分布。常用XML配置属性(1)&nbs
- 一、引言我们都知道,数据库连接是很珍贵的资源,频繁的开关数据库连接是非常浪费服务器的CPU资源以及内存的,所以我们一般都是使用数据库连接池来
- @Autowired注入依赖失败的问题1、现象描述在Spring Boot项目中使用@Autowired注解,程序启动时发现服务启动失败,提