Dav*_*ade 4 entity-framework entity-framework-5
我试图在我的网站上使用基于实体框架代码的迁移.我目前有一个包含多个项目的解决方案.我想要初始化数据库的Web API项目和另一个名为DataLayer项目的项目.我已在DataLayer项目中启用了迁移并创建了一个初始迁移,我希望它将用于创建数据库(如果它不存在).
这是我启用迁移时获得的配置
public sealed class Configuration : DbMigrationsConfiguration<Harris.ResidentPortal.DataLayer.ResidentPortalContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(Harris.ResidentPortal.DataLayer.ResidentPortalContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
}
}
Run Code Online (Sandbox Code Playgroud)
我创建之后对此进行的唯一更改是将其从内部更改为公共,以便WebAPI可以看到它并在其databaseinitializer中使用它.下面是我用来尝试初始化数据库的Application_Start代码中的代码
Database.SetInitializer(new MigrateDatabaseToLatestVersion<ResidentPortalContext, Configuration>());
new ResidentPortalUnitOfWork().Context.Users.ToList();
Run Code Online (Sandbox Code Playgroud)
如果我运行它,无论数据库是否存在,我都会收到以下错误
目录查找文件"C:\ Users\Dave\Documents\Visual Studio 2012\Projects\ResidentPortal\Harris.ResidentPortal.WebApi\App_Data\Harris.ResidentPortal.DataLayer.ResidentPortalContext.mdf"失败,出现操作系统错误2(系统找不到指定的文件.)
CREATE DATABASE失败.无法创建列出的某些文件名.检查相关错误.
看起来它正在寻找数据库的完全错误的地方.它似乎与我正在初始化数据库的这种特殊方式有关,因为如果我将代码更改为以下内容.
Database.SetInitializer(new DropCreateDatabaseAlways<ResidentPortalContext>());
new ResidentPortalUnitOfWork().Context.Users.ToList();
Run Code Online (Sandbox Code Playgroud)
数据库将在需要的位置正确创建.
我对造成它的原因感到茫然.可能是我需要在配置类中添加其他东西,还是与我的所有迁移信息都在DataLayer项目中但我从WebAPI项目中调用它这一事实有关?
我已经想出了如何为此进程创建动态连接字符串.您需要先将此行添加到Web或App.Config上的EntityFramework条目中,而不是默认情况下放在那里的行.
<defaultConnectionFactory type="<Namespace>.<ConnectionStringFacotry>, <Assembly>"/>
Run Code Online (Sandbox Code Playgroud)
这告诉程序你有自己的工厂将返回DbConnection.下面是我用来制作自己工厂的代码.部分原因在于,一群程序员使用相同的代码集,但有些人使用SQL Express,而其他人使用完整的SQL Server.但这会给你一个例子来满足你的需求.
public sealed class ResidentPortalConnectionStringFactory: IDbConnectionFactory
{
public DbConnection CreateConnection(string nameOrConnectionString)
{
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(ConfigurationManager.ConnectionStrings["PortalDatabase"].ConnectionString);
//save off the original catalog
string originalCatalog = builder.InitialCatalog;
//we're going to connect to the master db in case the database doesn't exist yet
builder.InitialCatalog = "master";
string masterConnectionString = builder.ToString();
//attempt to connect to the master db on the source specified in the config file
using (SqlConnection conn = new SqlConnection(masterConnectionString))
{
try
{
conn.Open();
}
catch
{
//if we can't connect, then append on \SQLEXPRESS to the data source
builder.DataSource = builder.DataSource + "\\SQLEXPRESS";
}
finally
{
conn.Close();
}
}
//set the connection string back to the original database instead of the master db
builder.InitialCatalog = originalCatalog;
DbConnection temp = SqlClientFactory.Instance.CreateConnection();
temp.ConnectionString = builder.ToString();
return temp;
}
}
Run Code Online (Sandbox Code Playgroud)
一旦我这样做,我就可以在我的Global.asax中运行此代码而没有任何问题
Database.SetInitializer(new MigrateDatabaseToLatestVersion<ResidentPortalContext, Configuration>());
using (ResidentPortalUnitOfWork temp = new ResidentPortalUnitOfWork())
{
temp.Context.Database.Initialize(true);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6499 次 |
| 最近记录: |