至于DataDirectory的1些想想,WinForm程序中两份mdf文件难题的消除

小编在运用Entity
Framework中的Scaffolding机制自动创设拓展名叫mdf的数据库及表单时,境遇如下的荒谬:

在档次中用程序中放置mdf文件的方法来实行SQLServer数据库开发相当有利于,用来公布开源项目等很便利,点击就能够运维,免布局,尤其是在教学中用起来更为便利,老师不用先将数据库文件detach再发放学员,学生也不用将数据库文件attach。接纳项目中放置mdf文件的章程,老师把教学的代码发给学员,学生打开就足以运作。我在传智播客.net培养和陶冶班教学中正是用的这种艺术开始展览讲解。

在档次中用程序中置放mdf文件的不二等秘书籍来举办SQLServer数据库开发非常便于,用来发表开源项目等很便宜,点击就能够运维,免布局,特别是在教学中
用起来更为便利,老师不用先将数据库文件detach再发放学生,学生也不用将数据库文件attach。选用项目中放到mdf文件的主意,老师把教学的代
码发给学生,学生打开就足以运作。我在传智播客.net培养和陶冶班教学中便是用的这种艺术进行教学。

在品种中用程序中放置mdf文件的章程来拓展SQLServer数据库开发分外方便,用来公布开源项目等很有益于,点击就足以运作,免布局,尤其是在教学中用起来尤其惠及,老师不用先将数据库文件detach再发给学生,学生也不用将数据库文件attach。采纳项目中放置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.

在ASP.net程序中要是将mdf文件放到项目标App_Data文件夹即可,在一而再字符串中应用
Data
Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\CallCenter.mdf;Integrated
Security=True;User Instance=True
做连接字符串即可。

在ASP.net程序中一经将mdf文件放到项指标App_Data文件夹即可,在一而再字符串中应用
Data
Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\CallCenter.mdf;Integrated
Security=True;User Instance=True
做连接字符串即可。

在ASP.net程序中倘使将mdf文件放到项目的App_Data文件夹即可,在两次三番字符串中使用
Data
Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\CallCenter.mdf;Integrated
Security=True;User Instance=True
做连接字符串即可。


然而在WinForm先后中,倘诺在类型的App_Data文件夹中新建2个mdf文件,然后用
Data
Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\CallCenter.mdf;Integrated
Security=True;User Instance=True
开始展览连接会提醒找不到CallCenter.mdf。原来WinForm程序并不会去App_Data中找mdf文件。原来在ASP.net中DataDirectory的值是日前项目标App_Data路径,而WinForm中的DataDirectory值则是现阶段项目标路径,因而Winform中mdf文件不用放到App_Data中,放到项目根目录下就足以。

唯独在WinForm主次中,假诺在类型的App_Data文件夹中新建三个mdf文件,然后用
Data
Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\CallCenter.mdf;Integrated
Security=True;User Instance=True
进展连接会提示找不到CallCenter.mdf。原来WinForm程序并不会去App_Data中找mdf文件。原来在ASP.net中
DataDirectory的值是眼下项指标App_Data路径,而WinForm中的DataDirectory值则是当下项指标门道,由此Winform中mdf文件不用放到App_Data中,放到项目根目录下就能够。

不过在WinForm先后中,如若在档次的App_Data文件夹中新建三个mdf文件,然后用
Data
Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\CallCenter.mdf;Integrated
Security=True;User Instance=True
举行连接会提示找不到CallCenter.mdf。原来WinForm程序并不会去App_Data中找mdf文件,在ASP.net中DataDirectory的值是现阶段项目标App_Data路径,而WinForm中的DataDirectory值则是当前项指标途径,因而Winform中mdf文件不用放到App_Data中,放到项目根目录下就足以。

 

至于DataDirectory的1些想想,WinForm程序中两份mdf文件难题的消除。可是新题材随即又来了,在WinForm中用那种办法开发的时候偶然改了档次中mdf文件中的表中的数额恐怕表结构,运营的时候却发现运维时经进程序读取的多少依旧表结构未有变,而有时调节和测试时Insert插入的多寡在此番调节和测试的时候居然从未了。经过切磋发现,WinForm程序运行的时候总是的是bin/Debug下的mdf文件,而不是项目中的mdf文件,这是和ASP.net程序行为差别的地点。每一遍程序爆发Build行为的时候,项目中的mdf就会覆盖bing/Debug下的mdf文件,也正是有五个mdf文件的存在,项目中的mdf也正是“源文件”。固然能够通过修改文件的“BuildToOuput”属性来壹些缓解难点,然则还是否很圆满。

唯独新题材随即又来了,在WinForm中用那种措施支付的时候偶然改了连串中mdf文件中的表中的数量照旧表结构,运营的时候却发现运行时通进程序读
取的数目照旧表结构未有变,而有时调节和测试时Insert插入的数额在此次调节和测试的时候甚至未有了。经过钻探发现,WinForm程序运营的时候总是的是
bin/Debug下的mdf文件,而不是类别中的mdf文件,这是和ASP.net程序作为不一致的地点。每一趟程序发生Build行为的时候,项目中的
mdf就会覆盖bing/Debug下的mdf文件,也正是有四个mdf文件的留存,项目中的mdf也正是“源文件”。固然能够经过改动文件的
“BuildToOuput”属性来部分消除问题,不过仍旧不是很周到。

可是新题材随即又来了,在WinForm中用那种措施开发的时候偶然改了连串中mdf文件中的表中的多少或然表结构,运营的时候却发现运转时经进度序读取的数据也许表结构未有变,而有时调节和测试时Insert插入的数量在此次调节和测试的时候依旧从未了。经过研商发现,WinForm程序运维的时候总是的是bin/Debug下的mdf文件,而不是项目中的mdf文件,那是和ASP.net程序行为分歧的地点。每一遍程序发生Build行为的时候,项目中的mdf就会覆盖bin/Debug下的mdf文件,也正是有八个mdf文件的留存,项目中的mdf也正是“源文件”。固然能够透过修改文件的“BuildToOuput”属性来一些消除难点,但是照旧不是很周到。

率先想起一下创制这几个顺序的步子:

有3个相比很直白的想法,就是让程序去老是项目中的mdf文件,而不是连接bin/Debug下十分。
经过询问资料找到了修章,在Program.cs文件Main函数最开首投入如下代码:
string dataDir = AppDomain.CurrentDomain.BaseDirectory;
            if (dataDir.EndsWith(@”\bin\Debug\”)
                || dataDir.EndsWith(@”\bin\Release\”))
            {
                dataDir =
System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName;
                AppDomain.CurrentDomain.SetData(“DataDirectory”,
dataDir);
            }

有二个比较很间接的想法,就是让程序去老是项目中的mdf文件,而不是连接bin/Debug下格外。
透过询问资料找到了改动章程,在Program.cs文件Main函数最开端参与如下代码:
string dataDir = AppDomain.CurrentDomain.BaseDirectory;
            if (dataDir.EndsWith(@”\bin\Debug\”)
                || dataDir.EndsWith(@”\bin\Release\”))
            {
                dataDir =
System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName;
                AppDomain.CurrentDomain.SetData(“DataDirectory”,
dataDir);
            }

有2个比较很直白的想法,正是让程序去老是项目中的mdf文件,而不是连接bin/Debug下丰富。
由此查询资料找到了修章,在Program.cs文件Main函数最伊始加入如下代码:

壹、创立几个Console控制台应用程序,程序集名称及命名空间为ConsoleApp;

规律简单分析:连接字符串中的DataDirectory的值便是经过AppDomain.CurrentDomain.SetData赋值过去的,要是当前程序的目录以”\bin\Debug\”或者”\bin\Release\”则以为它是运作在VisualStudio环境中,就取项目标目录然后赋值给DataDirectory这几个key。既然是CurrentDomain.SetData,臆度对于非暗许AppDomain中的数据库连接代码大概会不起作用(只是估计,没注脚),那就要供给创设子AppDomain的时候再去赋值了。

原理简单解析:连接字符串中的DataDirectory的值正是通过AppDomain.CurrentDomain.SetData赋值过去的,尽管当前先后的目录以”\bin\Debug\亚洲必赢官网,”或者”\bin\Release\”则以为它是运转在VisualStudio环境中,就取项目标目录然后赋
值给DataDirectory那个key。既然是CurrentDomain.SetData,测度对于非私下认可AppDomain中的数据库连接代码恐怕会不起效能(只是测度,没表达),那即将供给创立子AppDomain的时候再去赋值了。

string dataDir = AppDomain.CurrentDomain.BaseDirectory;
            if (dataDir.EndsWith(@”\bin\Debug\”)
                || dataDir.EndsWith(@”\bin\Release\”))
            {
                dataDir =
System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName;
                AppDomain.CurrentDomain.SetData(“DataDirectory”,
dataDir);
            }

二、使用程序包控制台管理器将Entity Framework包罗到此程序中,代码如下:

地方的代码依然有几许机密的bug的,比如正式的周转的时候exe被很杯具的放置了某些bin\Debug目录下,就会有难点,但是想想正式生产环境运转的时候自然不会用那种AttachDbFilename格局,这种办法只设有于开发环境,由此也就睁2头眼闭2只眼了,呵呵。

地点的代码依然有一些诡秘的bug的,比如正式的周转的时候exe被很杯具的放权了有些bin\Debug目录下,就会不正常,然则想想正式生产环境运营的时候自然不会用那种AttachDbFilename格局,那种艺术只设有于开发环境,因而也就睁1只眼闭一头眼了,呵呵。

原理简单分析:连接字符串中的DataDirectory的值便是由此AppDomain.CurrentDomain.SetData赋值过去的,假使当前先后的目录以”\bin\Debug\”或者”\bin\Release\”则以为它是运转在VisualStudio环境中,就取项指标目录然后赋值给DataDirectory那些key。既然是CurrentDomain.SetData,预计对于非暗中认可AppDomain中的数据库连接代码大概会不起成效(只是猜想,没表明),那即将需求创设子AppDomain的时候再去赋值了。

PM> install-package Entity Framework

参考资料:

[引用来自 www.rupeng.com/forum/thread-11九九零-1-一.html]

上面包车型地铁代码仍然有好几暧昧的bug的,比如正式的运转的时候exe被很杯具的停放了有些bin\Debug目录下,就会有标题,可是想想正式生产条件运转的时候一定不会用那种AttachDbFilename格局,那种格局只存在于付出环境,由此也就睁一头眼闭2只眼了,呵呵。

叁、在App.Config文件军长以下内容插入到configuration节点:

参考资料:http://weblogs.asp.net/avnerk/archive/2005/12/25/433981.aspx
http://www.cnblogs.com/dajianshi/archive/2007/07/06/808495.html

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

如鹏网.Net培训班正在申请,有网络的地点就能够参预如鹏网的就学,学完就能高薪就业,点击那里通晓

四、在控制台编写以下代码:

 

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; }
    }
}

 
  三年前假若懂“三层架构”就足以说“通晓分层架构”;未来则要求懂IOC(AutoFac等)、CodeFirst、lambda、DTO等才值钱;

5、运转此程序,发现先后无法按本身想要的结果运维,出现在最前边出现的荒唐。

    三年前假设会SQLServer就能够说自身“通晓数据库开发”;今后则需还须要控制MySQL等开源数据库才能说是“.Net开源”时期的程序员;


    三年前尽管会议及展览开用户上传内容的安全性处理即可;今后则要求熟谙云存款和储蓄、CDN等才能在云总结时期非常熟练;

由此查阅出错的信息,发现

    三年前如若精通Lucene.Net就会说本人“领悟站内搜寻引擎开发”;今后大家都用ElasticSearch了,你还用Lucene.Net就太老土了;

AttachDBFilename=|DataDirectory|\MusicDBContext.mdf

    三年前发邮件还是用SmtpClient;今后做大型网址发邮件必须用云邮件引擎;

有标题,而那又是从未有过难题的,那到底是怎么回事?为何会产出谬误?

    三年前缓存正是Context.Cache;今后则是Redis、Memcached的天下;

于是乎,通过MSDN查找有关资料,通过以下方法获得DataDirectory内定的路线是何许:

    如鹏网再次引领.Net社区技术时髦!点击那里了解如鹏网.Net最新课程

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 

二)如若是ASP.NET程序,DataDirectory的初阶化目录为App_Data。

叁)关于越来越多的|DataDirectory|知识,请参见如下:

   
 

   
 

   
 

   

 

网站地图xml地图