ef核心-如何将表从一种模式复制到具有多对多关系的另一种模式?

时间:2019-01-21 12:47:20

标签: c# asp.net-core ef-code-first entity-framework-core

我的主模式中有表和映射,创建另一个模式时需要重新创建它们。我不知道什么是最好的方法,但是现在我这样做:

            var permissions = context.Permissions.ToList();//master context
            var roles = context.TenantRoles.ToList();

            var permRoles = context.RolePermissions.ToList();
            using (var tenantContext = new TenantContext(newTenant.Id.ToString()))
            {
                RelationalDatabaseCreator creator =
                    (RelationalDatabaseCreator) tenantContext.Database.GetService<IRelationalDatabaseCreator>();
                creator.CreateTables();
                tenantContext.TenantUsers.Add(new TenantUser {UserId = user.Id});
                //tenantContext.Permissions.AddRange(permissions);
                //tenantContext.TenantRoles.AddRange(roles);
                foreach (var role in roles)
                {
                    tenantContext.TenantRoles.Add(new Role {Name = role.Name, CanBeDeleted = role.CanBeDeleted});
                }

                foreach (var permission in permissions)
                {
                    tenantContext.Permissions.Add(new Permission {Name = permission.Name});
                }
                foreach (var map in permRoles)
                {
                    tenantContext.RolePermissions.Add(new RolePermission
                    {
                        Permission = tenantContext.Permissions.FirstOrDefault(p=>p.Name == map.Permission.Name),
                        Role = tenantContext.TenantRoles.FirstOrDefault(r=>r.Name == map.Role.Name)
                    });

                }
                tenantContext.SaveChanges();

            }

SaveChanges()上出现此异常:

  

“实体类型'RolePermission'上的属性'RoleId'具有一个临时值。要么显式设置一个永久值,要么确保将数据库配置为为此属性生成值。”

如果我手动创建映射(通过创建角色,权限并映射它们的服务),则一切正常,因此我想这并不是因为多对多关系。 RolePermissionRolePermission类是:

public class Permission
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<RolePermission> RolePermissions { get; set; }
}
public class Role
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<RolePermission> RolePermissions { get; set; }
    public List<UserRole> UserRoles { get; set; }
    public bool CanBeDeleted { get; set; }
}
public class RolePermission
{
    public int Id { get; set; }
    public int RoleId { get; set; }
    public Role Role { get; set; }
    public int PermissionId { get; set; }
    public Permission Permission { get; set; }
}

和OnModelCreating

protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema(SchemaName);

        modelBuilder.Entity<TestEntity>().ToTable("TestEntity", SchemaName);
        modelBuilder.Entity<Document>().ToTable("Documents", SchemaName);
        modelBuilder.Entity<Role>().ToTable("Roles", SchemaName);
        modelBuilder.Entity<Permission>().ToTable("Permissions", SchemaName);
        modelBuilder.Entity<TenantUser>().ToTable("TenantUsers", SchemaName);

        modelBuilder.Entity<UserRole>()
            .HasKey(bc => new { bc.RoleId, bc.TenantUserId });
        modelBuilder.Entity<UserRole>()
            .HasOne(bc => bc.Role)
            .WithMany(b => b.UserRoles)
            .HasForeignKey(bc => bc.RoleId);
        modelBuilder.Entity<UserRole>()
            .HasOne(bc => bc.TenantUser)
            .WithMany(c => c.UserRoles)
            .HasForeignKey(bc => bc.TenantUserId);
        modelBuilder.Entity<UserRole>().ToTable("UserRole", SchemaName);

        modelBuilder.Entity<RolePermission>()
            .HasKey(bc => new { bc.RoleId, bc.PermissionId });
        modelBuilder.Entity<RolePermission>()
            .HasOne(bc => bc.Role)
            .WithMany(b => b.RolePermissions)
            .HasForeignKey(bc => bc.RoleId);
        modelBuilder.Entity<RolePermission>()
            .HasOne(bc => bc.Permission)
            .WithMany(c => c.RolePermissions)
            .HasForeignKey(bc => bc.PermissionId);
        modelBuilder.Entity<RolePermission>().ToTable("RolePermissions", SchemaName);

        base.OnModelCreating(modelBuilder);
    }

复制具有关系的表的最佳方法是什么,为什么会出现此错误?

1 个答案:

答案 0 :(得分:0)

添加角色和权限后,还需要使用tenantContext.SaveChanges()。否则,使用EF核心添加RolePermissions时将无法检测到添加的数据。

foreach (var role in roles)
{
    tenantContext.TenantRoles.Add(new Role { Name = role.Name, CanBeDeleted = role.CanBeDeleted });
}
tenantContext.SaveChanges();

foreach (var permission in permissions)
{
    tenantContext.Permissions.Add(new Permission { Name = permission.Name });
}
tenantContext.SaveChanges();

foreach (var map in permRoles)
{
    tenantContext.RolePermissions.Add(new RolePermission
    {
        Permission = tenantContext.Permissions.FirstOrDefault(p => p.Name == map.Permission.Name),
        Role = tenantContext.TenantRoles.FirstOrDefault(r => r.Name == map.Role.Name)
    });

}
tenantContext.SaveChanges();