首页 > 解决方案 > System.Data.Entity.Migrations.AddOrUpdate 的 EF6 数据播种问题

问题描述

EF 6.2、SQL Server 2016 开发者版、.Net 4.5.2

我在使用AddOrUpdate扩展方法时遇到了一些问题。据我了解该方法,应该使用 lambda 表达式定义应该用于确定是否要更新或添加记录的唯一字段。但我的似乎忽略了这一点,并试图每次都添加。此示例使用身份类 AspNetRole,但上下文中的所有实体都发生了相同的问题。

public class UserSeeder
{    
    public static void Seed(MyIdentityDbContext context)
    {


        HashSet<AspNetRole> roles = new HashSet<AspNetRole>();

        AspNetRole systemAdmin = new AspNetRole() { Id = "269E684F-9542-4F6A-8029-7516AA2ECD61", Name = "System Admin" };
        AspNetRole admin = new AspNetRole() { Id = "BE70FDF9-FCD5-4894-AE71-DA324A7D751E", Name = "Administrator" };
        AspNetRole normalUser = new AspNetRole() { Id = "D9C66DC0-190F-463A-88B0-8E1E4ED96BAF", Name = "User" };

        roles.Add(systemAdmin);
        roles.Add(admin);
        roles.Add(normalUser);

        foreach (AspNetRole role in roles)
        {
            context.Roles.AddOrUpdate(r =>r.Id, role);
            //context.Roles.AddOrUpdate(role);
            //both throw same error
        }
        context.SaveChanges();
    }
}

并在启用迁移生成的 Configuration.cs 文件中。

//  This method will be called after migrating to the latest version.
protected override void Seed(MyIdentityDbContext context)
{
    UserSeeder.Seed(context);
    base.Seed(context);
}

这是我使用 lambda 调用和传入对象时遇到的错误。我怀疑有些配置我没有正确设置,因为这是上周工作的,当我检查 git 时,没有对 DAL 项目的任何文件进行任何更改。

违反主键约束“PK_dbo.AspNetRoles”。无法在对象“dbo.AspNetRoles”中插入重复键。重复键值为 (269E684F-9542-4F6A-8029-7516AA2ECD61)。

此外,数据库是最新的,应用程序在运行时不会抛出任何数据访问错误,因此连接良好且模型同步。我们只是无法让种子方法按照示例所示的方式工作。

标签: c#entity-framework-6sql-server-2016

解决方案


您可以检查角色是否已经存在,如果存在则更新,否则添加新角色

    public static void Seed(MyIdentityDbContext context)
    {
        HashSet<AspNetRole> roles = new HashSet<AspNetRole>();
        AspNetRole systemAdmin = new AspNetRole() { Id = "269E684F-9542-4F6A-8029-7516AA2ECD61", Name = "System Admin" };
        AspNetRole admin = new AspNetRole() { Id = "BE70FDF9-FCD5-4894-AE71-DA324A7D751E", Name = "Administrator" };
        AspNetRole normalUser = new AspNetRole() { Id = "D9C66DC0-190F-463A-88B0-8E1E4ED96BAF", Name = "User" };

        roles.Add(systemAdmin);
        roles.Add(admin);
        roles.Add(normalUser);

        foreach (AspNetRole role in roles)
        {
            AspNetRole dbrole = context.Roles.FirstOrDefault(r => r.Id.ToLower() == role.Id.ToLower());
            if (dbrole != null)
            {
                dbrole.Name = role.Name;
                context.Roles.AddOrUpdate(dbrole);
            }
            else
            {
                context.Roles.Add(role);
            }           
        }
        context.SaveChanges();
    }

推荐阅读