本文介绍了如何在控制台应用程序中定义为DataDirectory目录使用的ConnectionString代码的EntityFramework迁移第一工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试设置位置 MyProject\App_Data\Cos.mdf 的App.config 数据库

 <&是connectionStrings GT; 
<添加名称=DefaultConnection的connectionString =数据源=(的LocalDB)\v11.0; AttachDbFilename = | DataDirectory目录| \Cos.mdf;初始目录=产地来源证;集成安全性= TRUE; MultipleActiveResultSets =真的providerName =System.Data.SqlClient的/>
< /&是connectionStrings GT;

的Program.cs 我写的:

 静态无效的主要(字串[] args){

串亲戚= @.. \ ..\App_Data\Cos.mdf;
串绝对= Path.GetFullPath(相对);

AppDomain.CurrentDomain.SetData(DataDirectory目录,绝对);
Console.WriteLine(绝对);
Console.ReadKey();
}

显示的路径是(我贴吧表明,我没有做错误):





但后来当我在软件包管理控制台中输入启用的迁移变更 AutomaticMigrations 为true,然后键入更新数据库我得到错误:



无法附加文件C:\Users\s8359_000\Documents\Visual工作室2013\Projects\Projekt5 - kopia\Projekt5\bin\Debug\Cos.mdf'数据库'因为'。



为什么.NET试图在调试目录下创建我的数据库?我通过15名受试者继续计算器关于这一主题,它看起来像所有人都在重复这不工作的答案。



编辑答案SRUTZKY
是的,你说得对存在误差。我试过你的答案后,几个组合,遗憾的是没有工作。



 <&是connectionStrings GT; 
<添加名称=DefaultConnection的connectionString =数据源=(的LocalDB)\v11.0; AttachDbFilename = | DataDirectory目录| \baza.mdf;初始目录=巴扎;集成安全性= TRUE; MultipleActiveResultSets =真的providerName =System.Data.SqlClient的/>
< /&是connectionStrings GT;

和主

 静态无效的主要(字串[] args){

Console.WriteLine(BEFORE:+ AppDomain.CurrentDomain.GetData(DataDirectory目录));
串亲戚= @.. \..\App_Data\Cos.mdf
串绝对= Path.GetFullPath(相对);
绝对= Path.GetDirectoryName(@absolute);
AppDomain.CurrentDomain.SetData(DataDirectory目录,@absolute);
Console.WriteLine(@absolute);
Console.WriteLine(AppDomain.CurrentDomain.GetData(DataDirectory目录));
Console.ReadKey();
}



然后我得到控制台:





和删除后,迁移目录,启用的迁移,自动迁移到真正的,更新数据库我得到:



解决方案

Problem 1 (of 2)

When you set the value of DataDirectory, it needs to be a directory, not a file. You are passing in the value of the absolute variable which is:

C:\Users\s8359_000\Documents\Visual Studio 2013\Projects\Projekt5 — kopia\Projekt5\App_Data\Cos.mdf

and which contains the filename. That is not valid. DataDirectory is a substitution value, so specifying:

AttachDbFilename=|DataDirectory|\Cos.mdf

in the connection string would translate into:

C:\Users\s8359_000\Documents\Visual Studio 2013\Projects\Projekt5 — kopia\Projekt5\App_Data\Cos.mdf\Cos.mdf

That is not a valid path. So it appears that .NET sees that the value of DataDirectory is not valid and does not use it and hence starts in the current working directory.

Use Path.GetDirectoryName(relative) instead of Path.GetFullPath(relative) to set the value of absolute and it should work as it will set the value of DataDirectory to be:

C:\Users\s8359_000\Documents\Visual Studio 2013\Projects\Projekt5 — kopia\Projekt5\App_Data

The MSDN page for Connection Strings has some additional details towards the bottom, in the section titled, "Support for the |DataDirectory| Substitution String..."

Problem 2 (of 2)

  1. "DataDirectory" is set in the AppDomain.
  2. Console Apps have their own AppDomains that are created when they start and go away when they exit.
  3. Package Manager (where you are running Update-Database) does not have access to the AppDomain of your console app where you are setting the value of "DataDirectory".
  4. You need to either:

    1. programatically set "DataDirectory" in Package Manager, or
    2. programatically run "update-database" within the context of your console app

I don't know how to programatically interact with Package Manager, but I did manage to figure out how to programatically fire the "update-database" process. Just add the following line just after you set the value of "DataDirectory":

Database.SetInitializer(new
    MigrateDatabaseToLatestVersion<YourDataContextName, Configuration>()
 );

You will also need at least one, if not two, using statements:

  • using System.Data.Entity;
  • using ProjectName.Migrations; // namespace of Migrations\Configuration.cs

Please note that this alone does not create the database. Any pending changes will be published when you first access the database via the DbContext.

Example:

using System.Data.Entity;
using Projekt5.Migrations;

....

string relative = @"..\..\App_Data\Cos.mdf";
string absolute = Path.GetDirectoryName(absolute);
AppDomain.CurrentDomain.SetData("DataDirectory", absolute);
Database.SetInitializer(new
    MigrateDatabaseToLatestVersion<Projekt5Context, Configuration>()
 );
// database not created yet

using (var db = new Projekt5Context())
{
  db.Things.Add(new Thing { Name = "OMG This works!" });
  db.SaveChanges();
}
// database CREATED!

Also, you might need to call the following, one time, via Package Manager (it doesn't do anything immediately to the database so the connection string is not accessed):

Add-Migration InitialMigration

For more info, please see the MSDN page for Code First Migrations.

Once this line of code to call SetInitializer is there with MigrateDatabaseToLatestVersion, it does just that: each time it runs (which is why this is done at the beginning of the console app) it syncs any changes between what is in the "model" (that is now compiled into the Assembly) and the database, making sure that the database has the latest version. This assumes that any new tables are represented in the DbContext class. But no additional Package Manager commands need to be ran.

这篇关于如何在控制台应用程序中定义为DataDirectory目录使用的ConnectionString代码的EntityFramework迁移第一工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-06 01:53