每次运行应用程序时,都会将相同的对象添加到数据库中(重复)。
我的Global.asax
:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using WebApplication2.Migrations;
using WebApplication2.Models;
namespace WebApplication2 {
public class MvcApplication : System.Web.HttpApplication {
protected void Application_Start() {
Database.SetInitializer(new MigrateDatabaseToLatestVersion<ApplicationDbContext, Configuration>());
//Database.SetInitializer(new DropCreateDatabaseAlways<ApplicationDbContext>());
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
}
和我的Configuration.cs
Seed
方法:
namespace WebApplication2.Migrations
{
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
using WebApplication2.Models;
internal sealed class Configuration : DbMigrationsConfiguration<WebApplication2.Models.ApplicationDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
ContextKey = "WebApplication2.Models.ApplicationDbContext";
}
protected override void Seed(WebApplication2.Models.ApplicationDbContext context) {
var persons = new List<Person> {
new Person{FirstName = "John", LastName = "Doe", CellNumber = "123-456-789", SecondaryPhoneNumber = "98873213", Address = "1street 2",BirthDate = DateTime.Now.Date, Pesel = "312312312", Notes = "Annoying"},
new Person{FirstName = "Anna", LastName = "Doe", CellNumber = "113-456-789", SecondaryPhoneNumber = "98873213", Address = "1street 2",BirthDate = DateTime.Now.Date, Pesel = "548555672", Notes = "Less Annoying"}
};
persons.ForEach(person => context.Persons.AddOrUpdate(person));
context.SaveChanges();
var meetings = new List<Meeting>{
new Meeting{PersonId = 1, Body = "Body of meeting", Date = DateTime.Now}
};
meetings.ForEach(meeting => context.Meetings.AddOrUpdate(meeting));
context.SaveChanges();
var statuses = new List<Status> {
new Status{Name = "OK"},
new Status {Name = "NOT_OK"}
};
statuses.ForEach(status => context.Statuses.AddOrUpdate(status));
context.SaveChanges();
}
}
}
每次运行应用Seed
都会添加重复记录:
我需要评论Seed方法的内容以防止添加重复项。
问题:(1)我应该更改什么才能运行Seed
方法,以便在迁移后重新创建数据库?
编辑:
在Seed
方法中有评论:
// 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" }
// );
//
但我的方法不仅在迁移后被称为ALWAYS。为什么会这样?
答案 0 :(得分:9)
this page (about halfway down)来自this answer
注意:向Seed方法添加代码是将固定数据插入数据库的众多方法之一。 另一种方法是向每个迁移类的Up和Down方法添加代码。 Up和Down方法包含实现数据库更改的代码。您将在“部署数据库更新”教程中看到它们的示例。
您还可以使用Sql方法编写执行SQL语句的代码。例如,如果您要将“预算”列添加到“部门”表并希望将所有部门预算初始化为$ 1,000.00作为迁移的一部分,则可以将以下代码行添加到该迁移的Up方法中:
Sql(&#34; UPDATE Department SET Budget = 1000&#34;);
您也可以考虑使用this answer中引用的AddOrUpdate
方法,该方法也可以用于您的目的。
我很快改变了我从上面链接的答案中获得的代码,所以如果下面的代码存在问题,请耐心等待。我相信这个概念应该还是比较清楚的。
context.People.AddOrUpdate(c => c.PK, new Person() { PK = 0, FirstName = "John", ... })
context.People.AddOrUpdate(c => c.PK, new Person() { PK = 1, FirstName = "Anna", ... })
答案 1 :(得分:6)
您可以完全访问Seed
方法中的上下文,因此您可以查询数据是否已存在。
例如,只有在表格为空时才可以对表进行播种...
protected override void Seed(WebApplication2.Models.ApplicationDbContext context) {
if (!context.Persons.Any())
{
var persons = new List<Person> {
new Person{FirstName = "John", LastName = "Doe", CellNumber = "123-456-789", SecondaryPhoneNumber = "98873213", Address = "1street 2",BirthDate = DateTime.Now.Date, Pesel = "312312312", Notes = "Annoying"},
new Person{FirstName = "Anna", LastName = "Doe", CellNumber = "113-456-789", SecondaryPhoneNumber = "98873213", Address = "1street 2",BirthDate = DateTime.Now.Date, Pesel = "548555672", Notes = "Less Annoying"}
};
persons.ForEach(person => context.Persons.Add(person));
context.SaveChanges();
}
if (!context.Meetings.Any())
{
var meetings = new List<Meeting>{
new Meeting{PersonId = 1, Body = "Body of meeting", Date = DateTime.Now}
};
meetings.ForEach(meeting => context.Meetings.Add(meeting));
context.SaveChanges();
}
if (!context.Statuses.Any())
{
var statuses = new List<Status> {
new Status{Name = "OK"},
new Status {Name = "NOT_OK"}
};
statuses.ForEach(status => context.Statuses.Add(status));
context.SaveChanges();
}
}
您也可以使用AddOrUpdate
,但是您需要告诉EF如何使用第一个参数检查记录是否存在...
protected override void Seed(WebApplication2.Models.ApplicationDbContext context) {
var persons = new List<Person> {
new Person{FirstName = "John", LastName = "Doe", CellNumber = "123-456-789", SecondaryPhoneNumber = "98873213", Address = "1street 2",BirthDate = DateTime.Now.Date, Pesel = "312312312", Notes = "Annoying"},
new Person{FirstName = "Anna", LastName = "Doe", CellNumber = "113-456-789", SecondaryPhoneNumber = "98873213", Address = "1street 2",BirthDate = DateTime.Now.Date, Pesel = "548555672", Notes = "Less Annoying"}
};
persons.ForEach(person => context.Persons.AddOrUpdate(p => new { p.FirstName, p.LastName }, person));
context.SaveChanges();
var meetings = new List<Meeting>{
new Meeting{PersonId = 1, Body = "Body of meeting", Date = DateTime.Now}
};
meetings.ForEach(meeting => context.Meetings.AddOrUpdate(m => m.Body, meeting));
context.SaveChanges();
var statuses = new List<Status> {
new Status{Name = "OK"},
new Status {Name = "NOT_OK"}
};
statuses.ForEach(status => context.Statuses.AddOrUpdate(s => s.Name, status));
context.SaveChanges();
}
答案 2 :(得分:1)
问题:(1)我应该改变什么,所以Seed方法只会运行 迁移后重新创建数据库?
如果您只需要在创建数据库时播种数据。在这种情况下,您可以从CreateDatabaseIfNotExist Initialiser创建数据库初始化程序。然后在DatabaseInitialiser类中,您可以使用您的数据覆盖种子方法,而不是MigrationConfiguration类。更多信息可以在附件链接中找到。
Database Initialization Strategies in Code-First:
但我的方法不仅在迁移后被称为ALWAYS。为什么 所以?
在迁移配置中。每次数据库迁移发生时都会调用种子方法。这就是为什么你的种子方法一直被调用的原因。
答案 3 :(得分:0)
var paidOutType = new List<PaidOutType>
{
new PaidOutType { PaidOutTypeID = 1, Code = "001", Description = "PAID OUT 1", PType = "1", Amount = 0, IsSalesSummery = true,DayFrom=1,DayTo=31 },
new PaidOutType { PaidOutTypeID = 2, Code = "002", Description = "PAID OUT 2", PType = "1", Amount = 0, IsSalesSummery = true,DayFrom=1,DayTo=31 },
new PaidOutType { PaidOutTypeID = 3, Code = "002", Description = "PAID OUT 3", PType = "1", Amount = 0, IsSalesSummery = true,DayFrom=1,DayTo=31 },
};
paidOutType.ForEach(u => smartPOSContext.PaidOutType.AddOrUpdate(u));
smartPOSContext.SaveChanges();
答案 4 :(得分:0)
这对我有用
答案 5 :(得分:-1)
首先,重置您的主键,以确保不会出现重复键
"ServerName localhost:8080"
然后使用// reset identity autoincrement to 0
context.Database.ExecuteSqlCommand("DBCC CHECKIDENT('tableName', RESEED, 0)");
方法播种数据
AddOrUpdate