Yod*_*oda 5 c# entity-framework seed duplicates asp.net-mvc-5.1
每次运行应用程序时,都会将相同的对象添加到数据库中(重复).
我的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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
和我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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
每次运行应用程序时都会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" }
// );
//
Run Code Online (Sandbox Code Playgroud)
但我的方法不仅在迁移后被称为ALWAYS.为什么会这样?
从这个页面(大约一半),这个来自这个答案
注意:向Seed方法添加代码是将固定数据插入数据库的众多方法之一.另一种方法是将代码添加到每个迁移类的Up和Down方法中.Up和Down方法包含实现数据库更改的代码.您将在"部署数据库更新"教程中看到它们的示例.
您还可以使用Sql方法编写执行SQL语句的代码.例如,如果您要将"预算"列添加到"部门"表并希望将所有部门预算初始化为$ 1,000.00作为迁移的一部分,则可以将以下代码行添加到该迁移的Up方法中:
Sql("UPDATE Department SET Budget = 1000");
您也可以考虑使用此答案中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", ... })
Run Code Online (Sandbox Code Playgroud)
您可以完全访问方法中的上下文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();
}
}
Run Code Online (Sandbox Code Playgroud)
你也可以使用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();
}
Run Code Online (Sandbox Code Playgroud)