【问题标题】:ASP.NET: How do I avoid duplicating Seed Data?ASP.NET:如何避免重复种子数据?
【发布时间】:2017-07-29 05:41:38
【问题描述】:

在启用自动迁移时,我正在使用在迁移文件夹下创建的 Configuration.cs 文件中的种子方法开发我的应用程序时播种数据。问题是,当我在更改或添加新模型后使用“update-database”命令时,它会重新播种数据,并在各处添加双条目。然后我必须手动检查并删除所有表中的所有内容。我的 SQL 服务器是一个单独的 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();
        }
    }
}

【问题讨论】:

    标签: c# entity-framework asp.net-core-mvc


    【解决方案1】:

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

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

    【讨论】:

    • 这可能是一个好方法,但如果你添加到 Seed 方法,它会中断。
    • @illug,为什么会坏掉?我在docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/…看到它
    • 如果您想使用 Seed 方法将新记录添加到 people 表中,除非您在运行 Seed 方法之前从表中删除所有内容,否则不会添加新记录,因为 .Any() 将检查仅当它包含任何记录时。
    • @illug,是的,但我认为他不会在迁移期间每次都添加新记录。
    • 不,很可能不会。也许我的英语妨碍了:) 我最初评论的意思是,如果您想使用 Seed 方法将更多数据放入数据库,然后使用 .Any 将强制您首先从表中删除。不过,使用 .AddOrUpdate 会很好地工作。话虽如此,我什至不确定 .AddOrUpdate 在 EF Core 中是否可用。
    【解决方案2】:

    试试

    context.people.AddOrUpdate()
    

    【讨论】:

      【解决方案3】:

      AddOrUpdate() 方法正是为此用途而设计的。

      如果不是所有属性都在 Seed 方法中明确说明,您仍然可能会遇到问题。例如,如果您要在构造函数中分配 GUID 字段或随机数。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-23
        • 1970-01-01
        • 2021-05-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多