我正在尝试使用基于Entity Framework代码的迁移到我的网站。我目前有一个包含多个项目的解决方案。我想要初始化数据库的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" }
// );
//
}
}
我在创建它之后对此进行的唯一更改是将其从内部更改为公共,以便WebAPI可以看到它并在其databaseinitializer中使用它。下面是我用来尝试初始化数据库的Application_Start代码中的代码
Database.SetInitializer(new MigrateDatabaseToLatestVersion<ResidentPortalContext, Configuration>());
new ResidentPortalUnitOfWork().Context.Users.ToList();
如果我运行它,无论数据库是否存在,我都会收到以下错误
文件“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();
数据库将在需要的位置正确创建。
我对造成它的原因感到茫然。可能是我需要在配置类中添加其他内容,还是与我的所有迁移信息都在DataLayer项目中但我从WebAPI项目中调用它这一事实有关?
答案 0 :(得分:8)
我已经想出了如何为此进程创建动态连接字符串。您需要先将此行添加到Web或App.Config上的EntityFramework条目中,而不是默认情况下放在那里的行。
<defaultConnectionFactory type="<Namespace>.<ConnectionStringFacotry>, <Assembly>"/>
这告诉程序你有自己的工厂将返回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;
}
}
一旦我这样做,我就可以在我的Global.asax中运行此代码而没有任何问题
Database.SetInitializer(new MigrateDatabaseToLatestVersion<ResidentPortalContext, Configuration>());
using (ResidentPortalUnitOfWork temp = new ResidentPortalUnitOfWork())
{
temp.Context.Database.Initialize(true);
}