威尼斯人线上娱乐

WinForm程序中两份mdf文件难题的化解,关于DataDirectory的部分盘算

9 4月 , 2019  

小编在运用Entity
Framework中的Scaffolding机制自动创设拓展名称叫mdf的数据库及表单时,碰着如下的错误:

在档次中用程序中放到mdf文件的章程来拓展SQLServer数据库开发格外有利,用来公布开源项目等很方便,点击就能够运营,免布局,越发是在教学中用起来更为便于,老师不用先将数据库文件detach再发放学生,学生也不用将数据库文件attach。选取项目中放到mdf文件的法子,老师把教学的代码发给学员,学生打开就足以运作。作者在传智播客.net培养和磨炼班教学中正是用的那种措施开始展览讲解。

威尼斯人线上娱乐 ,在档次中用程序中放置mdf文件的主意来拓展SQLServer数据库开发格外有利于,用来发布开源项目等很有益于,点击就能够运维,免布局,尤其是在教学中
用起来更为便于,老师不用先将数据库文件detach再发放学生,学生也不用将数据库文件attach。采取项目中放置mdf文件的不2诀要,老师把教学的代
码发给学生,学生打开就足以运作。小编在传智播客.net培养和磨炼班教学中就是用的那种措施展开教学。

在品种中用程序中置放mdf文件的法子来展开SQLServer数据库开发13分便于,用来宣布开源项目等很有益,点击就足以运作,免布局,尤其是在教学中用起来越发便于,老师不用先将数据库文件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程序中1经将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=.\WinForm程序中两份mdf文件难题的化解,关于DataDirectory的部分盘算。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”属性来一些消除难题,然而依然不是很周到。

率先想起一下创制这么些程序的步子:

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

有八个比较很直白的想法,正是让程序去老是项目中的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格局,那种格局只存在于付出条件,由此也就睁二只眼闭二头眼了,呵呵。

上边包车型客车代码仍然有几许私人住房的bug的,比如正式的运作的时候exe被很杯具的放权了有个别bin\Debug目录下,就会有标题,可是想想正式生产条件运维的时候一定不会用那种AttachDbFilename方式,那种办法只存在于开发条件,因而也就睁2头眼闭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-1壹九八7-壹-一.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培训班正在申请,有网络的地点就足以参预如鹏网的上学,学完就能高薪就业,点击那里通晓

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

 

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等才值钱;

五、运行此程序,发现先后不可能按本人想要的结果运维,出现在最前边出现的谬误。

    三年前借使会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。

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

   
 

   
 

   
 

   

 


相关文章

发表评论

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

网站地图xml地图