问题描述
我尝试设置位置 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)
- "DataDirectory" is set in the AppDomain.
- Console Apps have their own AppDomains that are created when they start and go away when they exit.
- 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". - You need to either:
- programatically set "DataDirectory" in Package Manager, or
- 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迁移第一工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!