WinForm程序中两份mdf文件难点的缓解,关于DataDirectory的有个别合计

小编在行使Entity
Framework中的Scaffolding机制自动创立拓展名叫mdf的数据库及表单时,蒙受如下的不当:

WinForm程序中两份mdf文件难点的缓解,关于DataDirectory的有个别合计。在类型中用程序中置放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文件夹中新建三个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”属性来1些化解难点,可是依旧不是很完美。

先是想起一下创制这么些程序的步骤:

有多个比较很直接的想法,就是让程序去老是项目中的mdf文件,而不是连接bin/Debug下11分。
经过查询资料找到了修章,在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);
            }

美高梅开户网址,有1个比较很直接的想法,就是让程序去老是项目中的mdf文件,而不是连接bin/Debug下10分。
经过询问资料找到了改动章程,在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方式,那种艺术只设有于付出环境,因而也就睁1头眼闭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-11九九零-一-一.html]

上边的代码依然有有个别暧昧的bug的,比如正式的运维的时候exe被很杯具的松手了有些bin\Debug目录下,就会有失水准,然而想想正式生产环境运维的时候肯定不会用那种AttachDbFilename方式,那种办法只设有于开发条件,由此也就睁一头眼闭三只眼了,呵呵。

叁、在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培训班正在申请,有互联网的地方就足以参与如鹏网的读书,学完就能高薪就业,点击那里驾驭

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

 
  三年前如若懂“3层架构”就足以说“明白分层架构”;今后则必要懂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地图