数据库已成功创建(与表格一样)但未播种。我花了几个小时阅读了大量的文章但却未能得到它。有什么建议吗?
另外,是否可以在客户端没有引用我的DatabaseContext的情况下调用初始化程序?
我已经包含了我能想到的所有相关代码。如果有任何其他方面的帮助,请告诉我。
我尝试过的事情:
编辑:非常奇怪的是它曾经工作过一次,但我不知道它是如何或为什么再次爆发。我假设连接字符串,但谁知道。
DatabaseInitializer.cs
public class DatabaseInitializer : DropCreateDatabaseIfModelChanges<DatabaseContext>
{
protected override void Seed(DatabaseContext context)
{
// Seeding data here
context.SaveChanges();
}
}
DatabaseContext.cs
public class DatabaseContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder mb)
{
// Random mapping code
}
public DbSet<Entity1> Entities1 { get; set; }
public DbSet<Entity2> Entities2 { get; set; }
}
Global.asax.cs - Application_Start()
protected void Application_Start()
{
Database.SetInitializer<DatabaseContext>(new DatabaseInitializer());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
客户端web.config
<connectionStrings>
<add name="DatabaseContext" connectionString="data source=.\SQLEXPRESS;Database=Database;Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
</connectionStrings>
为了记录,我在这里分享我的解决方案。无论如何,浏览所有评论都会很痛苦。最后,我将DatabaseInitializer和DatabaseContext放在不同的类中。我真的不明白,虽然这些微小的变化修复了它,但现在却是。
DatabaseInitializer.cs
public class DatabaseInitializer : CreateDatabaseIfNotExists<DatabaseContext>
{
protected override void Seed(DatabaseContext context)
{
// Seed code here
}
}
DatabaseContext.cs
public class DatabaseContext : DbContext
{
public DatabaseContext() : base("MyDatabase") { }
protected override void OnModelCreating(DbModelBuilder mb)
{
// Code here
}
public DbSet<Entity> Entities { get; set; }
// Other DbSets
}
Global.asax.cs - Application_Start()
protected void Application_Start()
{
Database.SetInitializer(new DatabaseInitializer());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
答案 0 :(得分:37)
这就是我的DbContext类看起来都很像它们的种子:
public class MyDbContext : DbContext
{
public DbSet<MyClass> MyClasses { get; set; }
protected override void OnModelCreating (DbModelBuilder modelBuilder)
{
base.OnModelCreating (modelBuilder);
modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention> ();
// Add any configuration or mapping stuff here
}
public void Seed (MyDbContext Context)
{
#if DEBUG
// Create my debug (testing) objects here
var TestMyClass = new MyClass () { ... };
Context.MyClasses.Add (TestMyClass);
#endif
// Normal seeding goes here
Context.SaveChanges ();
}
public class DropCreateIfChangeInitializer : DropCreateDatabaseIfModelChanges<MyDbContext>
{
protected override void Seed (MyDbContext context)
{
context.Seed (context);
base.Seed (context);
}
}
public class CreateInitializer : CreateDatabaseIfNotExists<MyDbContext>
{
protected override void Seed (MyDbContext context)
{
context.Seed (context);
base.Seed (context);
}
}
static MyDbContext ()
{
#if DEBUG
Database.SetInitializer<MyDbContext> (new DropCreateIfChangeInitializer ());
#else
Database.SetInitializer<MyDbContext> (new CreateInitializer ());
#endif
}
}
我已经使用过这种模式了几次,它对我来说非常好。
答案 1 :(得分:10)
即使在Seed
中正确调用Database.SetInitializer
,我的Application_Start
方法也未被调用...原因很简单:如果您不打算使用初始化程序,则可能根本无法调用还有任何实际使用数据库上下文的代码。
答案 2 :(得分:9)
这是我悲伤的小故事。
首先,经验教训:
所以,为了避免悲伤:
现在,悲伤:
答案 3 :(得分:3)
您可以调用update-database
在Configuration
类中手动运行种子方法。这也需要enable-migrations
。
PM> update-database
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
No pending code-based migrations.
Running Seed method.
internal sealed class Configuration : DbMigrationsConfiguration<ProjectManager.Data.Database.ProjectDb>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(ProjectManager.Data.Database.ProjectDb context)
{
context.Status.AddOrUpdate(
new Status() { Id = 1, Text = "New" },
new Status() { Id = 2, Text = "Working" },
new Status() { Id = 3, Text = "Completed" },
new Status() { Id = 4, Text = "Skipped" }
);
}
}
答案 4 :(得分:2)
Global.asax文件中的以下更改对我有用:
旧代码:
protected void Application_Start()
{
Database.SetInitializer<mycontextclassname>(new DropCreateDatabaseAlways<mycontextclassname>());
...
}
新守则:
protected void Application_Start()
{
Database.SetInitializer<mycontextclassname>(new DropCreateDatabaseAlways<mycontextclassname>());
Database.SetInitializer(new Initializer());
...
}
答案 5 :(得分:1)
我也很难调用Seed()。我非常感谢上面提到的所有有用的建议,并且使用DropCreateDatabaseAlways运气好了......但不是总是!!
最近,我在我的存储库的构造函数中添加了以下代码行,效果很好:
public CatalogRepository()
{
_formCatalog.FormDescriptors.GetType();
}
触发Seed()被调用就足够了。如果你已经尝试了这个答案之上的所有内容并且仍然没有运气,请试一试。祝你好运,这真是一段耗时的经历。
答案 6 :(得分:0)
您的示例中的种子事件只会被触发一次,因为您使用DropCreateDatabaseIfModelChanges可以将其更改为DropCreateDatabaseAlways我认为它应该每次都触发种子事件。
修改
这是我的DataContext
public WebContext()
{
DbDatabase.SetInitializer(new DropCreateDatabaseIfModelChanges<WebContext>());
}
答案 7 :(得分:0)
当我发现Code First Features时,这恰好发生在我身上。当您第一次使用Code First生成数据库而没有任何初始化策略时,通常会发生这种情况。
如果您稍后决定实施基于DropCreateDatabaseIfModelChanges
的策略,但未修改模型,则不会调用Seed
方法,因为数据库生成和您的策略只会下次更换模型时应用。
如果您遇到这种情况,只需尝试修改您的模型以测试此假设,我敢打赌,您的数据库将会被填充;)
我还没有解决方案,除了使用始终生成数据库的策略,但我真的不能将初始化策略放在DbContext中,因为这个类是goind用于你生产环境,虽然初始化策略似乎主要用于流畅的开发环境。
答案 8 :(得分:0)
我刚遇到这个问题。我已从Web.config文件中删除了“connectionstrings”部分,并且当前应用程序已开始运行 - 没有connectionstrings部分!我添加了部分,数据库不再播种。这不是一个合适的解决方案,但我只是在这里添加一个可以解决问题的数据点。
幸运的是,它只是一个小的“一次性”应用程序,我很快就会丢弃......
答案 9 :(得分:0)
更新以注意此答案不正确!我的数据库没有被播种的原因仍然是一个谜(但不是缺少默认的基础构造函数调用,如@JaredReisinger所述)
我很欣赏这个问题有点老了,但我最终在这里,所以其他人可能。这是我值得的值得:
即使我删除了数据库并使用DropDatabaseInitialiser再次启动,我的数据库也被创建得很好但没有播种。
在阅读上面的代码后,我注意到我的上下文构造函数是这个
public MyApp_Context()
{
// some code
}
而上面的例子对我的设置如下
public MyApp_Context() : base("name=MyApp_Context")
{
// some code
}
是的,我没有调用基础对象的构造函数!我不会期望除了播种之外的所有内容都可以在这种情况下工作,但这似乎是(可重复的)案例。
注意,我实际上并不需要在基础构造函数调用中提供上下文名称;我最初只是这样写的,因为我正在复制上面解决方案的格式。所以我的代码现在是这样的,种子在初始数据库创建时起作用。
public MyApp_Context() : base()
{
// some code
}
答案 10 :(得分:0)
谨慎地确保您不会多次声明您的上下文变量。如果在播种后再次声明它,种子将被覆盖。
答案 11 :(得分:0)
我遇到了同样的问题,并且在Global.asax
文件和Intializer
文件发生更改后都有效。我希望它对那些仍然存在数据播种问题的人有用。
Global.asax中的新代码:
protected void Application_Start()
{
Database.SetInitializer<mycontextclassname>(new DropCreateDatabaseAlways<mycontextclassname>());
Database.SetInitializer(new Initializer());
...
}
Intializer文件的代码:
public class Initializer : System.Data.Entity.DropCreateDatabaseAlways<Context>