C# ASP.NET:如何避免重复种子数据?

C# ASP.NET:如何避免重复种子数据?,c#,entity-framework,asp.net-core-mvc,C#,Entity Framework,Asp.net Core Mvc,当启用自动迁移时,我正在使用在migrations文件夹下创建的Configuration.cs文件中的seed方法开发应用程序时,我正在播种数据。问题是,当我在更改或添加新模型后使用“更新数据库”命令时,它会重新播种数据,并在所有地方添加两个条目。然后我必须检查并手动删除所有表中的所有内容。我的SQL server是一个单独的Azure实例 如何避免重复 namespace ChangeApp.Migrations { using Microsoft.AspNet.Identity.E

当启用自动迁移时,我正在使用在migrations文件夹下创建的Configuration.cs文件中的seed方法开发应用程序时,我正在播种数据。问题是,当我在更改或添加新模型后使用“更新数据库”命令时,它会重新播种数据,并在所有地方添加两个条目。然后我必须检查并手动删除所有表中的所有内容。我的SQL server是一个单独的Azure实例

如何避免重复

namespace ChangeApp.Migrations
{
    using Microsoft.AspNet.Identity.EntityFramework;
    using Models;
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;

    internal sealed class Configuration : DbMigrationsConfiguration<ChangeIT.Models.ChangeContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
        }

        protected override void Seed(ChangeIT.Models.ChangeContext context)
        {
            var people = new List<Person>
            {
                new Person { FirstName = "James", LastName = "Monroe", email = "david.bernstein@bdpint.com", manager = false, admin = false },
                new Person { FirstName = "Millard", LastName = "Fillmore", email = "dennis.yu@bdpint.com", manager = false, admin = false },
                new Person { FirstName = "John", LastName = "Adams", email = "jason.bullock@bdpint.com", manager = true, admin = false }
            };
            people.ForEach(s => context.people.Add(s));

            context.SaveChanges();

            var managers = new List<Manager>
            {
                new Manager { EngineerId = 3 }
            };

            managers.ForEach(s => context.managers.Add(s));
            context.SaveChanges();

            using (var db = new ApplicationDbContext())
            {
                if (db.Roles.Count() == 0)
                {
                    var roles = new List<IdentityRole>
                {
                    new IdentityRole("Admin"),
                    new IdentityRole("Manager"),
                    new IdentityRole("User")
                };
                    roles.ForEach(s => db.Roles.Add(s));
                    db.SaveChanges();
                }

            }


            var statuses = new List<Status>
            {
                new Status { StatusName = "Approved" },
                new Status { StatusName = "Pending Approval" },
                new Status { StatusName = "Completed" },
                new Status { StatusName = "Denied" }
            };

            statuses.ForEach(s => context.statuses.Add(s));
            context.SaveChanges();

            var systems = new List<SystemDetail>
            {
                new SystemDetail { SystemName = "Citrix" },
                new SystemDetail { SystemName = "VMWare" },
                new SystemDetail { SystemName = "SQL" }
            };

            systems.ForEach(s => context.systems.Add(s));
            context.SaveChanges();

            var changes = new List<Change>
            {
                new Change { EngineerId = 1, ManagerId = 3, ChangeDescription = "Update Chrome to version 52", ChangeDate = DateTime.Parse("2016-08-19 "), ChangeTime = DateTime.Parse("16:20"), SystemDetailId = 1, StatusId = 1 },
                new Change { EngineerId = 2, ManagerId = 4, ChangeDescription = "Put Cluster 1 blade 36 in maintenance mode. Replace memory in slot 2", ChangeDate = DateTime.Parse("2016-08-26"), ChangeTime = DateTime.Parse("16:20"),SystemDetailId = 2, StatusId = 2 }
            };

            changes.ForEach(s => context.changes.Add(s));
            context.SaveChanges();
        }
    }
}
namespace ChangeApp.Migrations
{
使用Microsoft.AspNet.Identity.EntityFramework;
使用模型;
使用制度;
使用System.Collections.Generic;
使用System.Data.Entity;
使用System.Data.Entity.Migrations;
使用System.Linq;
内部密封类配置:DBMigOptionsConfiguration
{
公共配置()
{
AutomaticMiggerationsEnabled=真;
}
受保护的覆盖无效种子(ChangeIT.Models.ChangeContext上下文)
{
var people=新列表
{
新人{FirstName=“詹姆斯”,LastName=“门罗”,email=“大卫。bernstein@bdpint.com,manager=false,admin=false},
新人{FirstName=“Millard”,LastName=“Fillmore”,email=“dennis。yu@bdpint.com,manager=false,admin=false},
新人{FirstName=“约翰”,LastName=“亚当斯”,email=“杰森。bullock@bdpint.com,manager=true,admin=false}
};
people.ForEach(s=>context.people.Add);
SaveChanges();
风险值管理器=新列表
{
新经理{engineerinid=3}
};
managers.ForEach(s=>context.managers.Add);
SaveChanges();
使用(var db=new ApplicationDbContext())
{
if(db.Roles.Count()==0)
{
var角色=新列表
{
新身份证(“管理员”),
新身份证(“经理”),
新标识(“用户”)
};
roles.ForEach(s=>db.roles.Add);
db.SaveChanges();
}
}
变量状态=新列表
{
新状态{StatusName=“已批准”},
新状态{StatusName=“待定批准”},
新状态{StatusName=“Completed”},
新状态{StatusName=“已拒绝”}
};
statuses.ForEach(s=>context.statuses.Add);
SaveChanges();
var系统=新列表
{
新系统详细信息{SystemName=“Citrix”},
新系统详细信息{SystemName=“VMWare”},
新系统详细信息{SystemName=“SQL”}
};
systems.ForEach(s=>context.systems.Add);
SaveChanges();
var changes=新列表
{
新更改{engineerinid=1,ManagerId=3,ChangeDescription=“将Chrome更新到52版”,ChangeDate=DateTime.Parse(“2016-08-19”),changedtime=DateTime.Parse(“16:20”),SystemDetailId=1,StatusId=1},
新更改{EngineerId=2,ManagerId=4,ChangeDescription=“将群集1刀片36置于维护模式。更换插槽2中的内存”,ChangeDate=DateTime.Parse(“2016-08-26”),ChangeTime=DateTime.Parse(“16:20”),SystemDetailId=2,StatusId=2}
};
changes.ForEach(s=>context.changes.Add);
SaveChanges();
}
}
}

只需添加到种子方法的开头:

 if (context.people.Any())
            {
                return;   // DB has been seeded
            }
试一试

AddOrUpdate()
方法正是用于此用途的

如果不是所有属性都在Seed方法中显式声明,那么仍然可能存在问题。例如,如果要在构造函数中指定GUID字段或随机数


AddOrUpdate()
将检查模型中的所有属性,如果不是所有属性都匹配,则在数据库中创建一个新条目。

这可能是一个好方法,但如果添加到Seed方法,它将中断。@illug,为什么它会中断?我在中看到,如果您想使用Seed方法向people表中添加新记录,则除非在运行Seed方法之前删除表中的所有内容,否则不会添加新记录。Any()只会检查它是否包含任何记录。@illug,是的,但我认为他不会在迁移过程中每次都添加新记录。否,很可能不是。可能是我的英语在妨碍:)我对原始注释的意思是,如果您想使用Seed方法将更多数据输入数据库,然后使用。Any将强制您首先从表中删除。不过,使用.AddOrUpdate会很好地工作。话虽如此,我甚至不确定。AddOrUpdate在EF Core中可用。
context.people.AddOrUpdate()