【4858.com】WinForm程序中两份mdf文件难点的消除,关于DataDirectory的片段思维

By admin in 4858.com on 2019年3月25日

小编在使用Entity
Framework中的Scaffolding机制自动创设拓展名为mdf的数据库及表单时,蒙受如下的荒唐:

在类型中用程序中置放mdf文件的主意来举办SQLServer数据库开发非凡便宜,用来发布开源项目等很有益,点击就能够运维,免布局,特别是在教学中用起来更为便利,老师不用先将数据库文件detach再发放学员,学生也不用将数据库文件attach。采纳项目中放置mdf文件的方法,老师把教学的代码发给学员,学生打开就能够运营。笔者在传智播客.net培养和锻练班教学中正是用的那种方法进行教学。

在档次中用程序中放到mdf文件的法门来开始展览SQLServer数据库开发非凡有利于,用来发表开源项目等很有利,点击就能够运作,免布局,尤其是在教学中
用起来尤其方便人民群众,老师不用先将数据库文件detach再发给学员,学生也不用将数据库文件attach。选拔项目中放到mdf文件的法子,老师把教学的代
码发给学员,学生打开就能够运转。作者在【4858.com】WinForm程序中两份mdf文件难点的消除,关于DataDirectory的片段思维。传智播客.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文件夹中新建一个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中,放到项目根目录下就足以。

 

然而新题材随即又来了,在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”属性来一些化解难题,可是依然不是很完美。

率先回想一下创办那一个程序的手续:

有二个相比很直接的想法,正是让程序去老是项目中的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函数最初叶参加如下代码:
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函数最开头投入如下代码:

① 、创立一个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形式,那种办法只设有于开发条件,由此也就睁3只眼闭二头眼了,呵呵。

上面的代码如故有一些机密的bug的,比如正式的周转的时候exe被很杯具的嵌入了有些bin\Debug目录下,就会有标题,不过想想正式生产环境运营的时候势必不会用那种AttachDbFilename方式,那种艺术只存在于付出环境,因而也就睁一只眼闭贰头眼了,呵呵。

原理简单解析:连接字符串中的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-11989-1-1.html]

下面包车型大巴代码依旧有有些私人住房的bug的,比如正式的周转的时候exe被很杯具的内置了有些bin\Debug目录下,就会有题目,可是想想正式生产条件运行的时候肯定不会用那种AttachDbFilename格局,那种办法只设有于开发条件,由此也就睁2头眼闭二只眼了,呵呵。

三 、在App.Config文件上将以下内容插入到configuration节点:

参考资料:http://weblogs.asp.net/avnerk/archive/2005/12/25/433981.aspx
4858.com ,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等才值钱;

伍 、运转此程序,发现先后不能够按自身想要的结果运转,出现在最前面现身的荒唐。

    三年前假诺会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 

2)即便是ASP.NET程序,DataDirectory的开头化目录为App_Data。

3)关于愈多的|DataDirectory|知识,请参考如下:

   
 

   
 

   
 

   

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有