我試圖創建一個新的數據庫使用實體框架的代碼第一個概念。但是,運行代碼時,不會創建數據庫(使用DropCreateDatabaseIfModelChanges
設置),儘管代碼運行良好。當我嘗試從數據庫中獲取某些內容時,發現以下異常。實體框架5代碼優先不創建數據庫
我的項目是使用一個單獨的DataAccess
層與通用服務和資源庫建設安裝。所以我所有的實體,存儲庫和數據庫上下文都在解決方案中的一個單獨項目中。我的global.asax
文件包含以下代碼段。
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyContext>());
這應該初始化一個新的數據庫,如果它不存在,對嗎?
我的數據庫上下文類看起來像這樣;
namespace Website.DAL.Model
{
public class MyContext : DbContext
{
public IDbSet<Project> Projects { get; set; }
public IDbSet<Portfolio> Portfolios { get; set; }
/// <summary>
/// The constructor, we provide the connectionstring to be used to it's base class.
/// </summary>
public MyContext()
: base("MyConnectionString")
{
}
static MyContext()
{
try
{
Database.SetInitializer<MyContext>(new DropCreateDatabaseIfModelChanges<MyContext>());
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// This method prevents the plurarization of table names
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention>();
}
}
}
我在互聯網上的幾個教程和文章後創建了這個類。這對我來說都是新的,但據我所知,一切似乎都是正確的。所以現在我正在使用的兩個實體。他們被稱爲'項目'和'投資組合'。他們看起來像這樣;
public class Portfolio
{
[Key]
public Guid Id { get; set; }
public String Name { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public bool IsPublished { get; set; }
public virtual ICollection<Project> Projects { get; set; }
}
而且
public class Project
{
[Key]
public Guid Id { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public bool IsPublished { get; set; }
public String Title { get; set; }
}
我使用一個外部服務器上運行的數據庫,它帶着我使用了託管服務提供商。我已經啓動了一個SQL Server數據庫,並且該數據庫的連接字符串位於網站項目的web.config
中。我已經嘗試刪除數據庫,並讓代碼重新創建它,但不幸的是沒有工作。我在這裏錯過了很明顯的東西嗎或者它可能是一個簡單的東西,作爲創建數據庫的服務器的訪問權限?
注:當我運行Database-Update -Script
命令生成SQL代碼,它似乎是正確的SQL語句來創建創建的所有表。
UPDATE 1: 好的,多虧了一些評論,我來得更進一步。我已經爲我的實體添加了兩個屬性來強制進行一些更改,並且我還創建了一個像這樣的自定義初始化程序;
public class ForceDeleteInitializer : IDatabaseInitializer<MyContext>
{
private readonly IDatabaseInitializer<MyContext> _initializer = new DropCreateDatabaseIfModelChanges<MyContext>();
public ForceDeleteInitializer()
{
//_initializer = new ForceDeleteInitializer();
}
public void InitializeDatabase(MyContext context)
{
//This command is added to prevent open connections. See http://stackoverflow.com/questions/5288996/database-in-use-error-with-entity-framework-4-code-first
context.Database.ExecuteSqlCommand("ALTER DATABASE borloOntwikkel SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
_initializer.InitializeDatabase(context);
}
}
我也從我的上下文的構造函數中刪除了初始化器,所以這意味着我已經刪除了這行代碼;
Database.SetInitializer<MyContext>(new DropCreateDatabaseIfModelChanges<MyContext>());
之後,我已經將這三行添加到我的全球。asax文件;
Database.SetInitializer(new ForceDeleteInitializer());
MyContext c = new MyContext();
c.Database.Initialize(true);
當調試我現在得到這個異常;
這給了我以下信息:
- 的InnerException說:提供程序未返回在InnerException一個 ProviderManifestToken
- 的InnerException說:「對於這種操作方式的連接masterdatabase是必需的。連接不能爲 因爲原來的連接是 已打開並且已從連接中刪除引用而使寬度爲'主'數據庫。請提供非開放連接」
這些動作後無法訪問數據庫,所以最有可能被刪除..
什麼都不可能瞭解這一點呢?這很可能是我無法訪問master數據庫,因爲我的主機提供商不會給我正確的訪問權限。
代碼和配置看起來確定,你可能停留在託管情況。 EF想要創建一個帶有特殊幫助表的Db(1或2個哈希)。也許你可以從本地Db編寫腳本並將其移至託管的Db? –
運行代碼的用戶帳戶是否具有刪除和創建數據庫的必要權限? – jlew
@亨克,我剛剛嘗試運行生成的SQL腳本。它用一條記錄爲我創建了一個__MigrationHistory表。我還通過添加'this.Database.Initialize(true)'行來修改我的上下文的構造函數。這並沒有給我一個錯誤,但也沒有創建任何表。然後我從MigrationHistory表中刪除記錄,並再次發生同樣的錯誤。所以我會嘗試在本地數據庫上運行它,看看會發生什麼。 – Rob