我试图创建一个新的数据库使用实体框架的代码第一个概念。但是,运行代码时,不会创建数据库(使用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