ef core - как скопировать таблицы из одной схемы в другую с отношением «многие ко многим»? - PullRequest
0 голосов
/ 21 января 2019

У меня есть таблицы и сопоставления в моей главной схеме, и мне нужно воссоздать их при создании другой схемы. Я не знаю, какой подход лучше, но сейчас я делаю это так:

            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() Я получаю это исключение:

"Свойство RoleId для типа сущности RolePermission имеет временное значение. Либо установите постоянное значение явно, либо убедитесь, что база данных настроена для генерации значений для этого свойства."

Если я создаю сопоставления вручную (через службу, которая создает роли, разрешения и сопоставляет их), все работает нормально, поэтому я полагаю, что это не из-за связи «многие ко многим». Role, Permission и RolePermission классы:

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 голосов
/ 22 января 2019

Вам также необходимо использовать tenantContext.SaveChanges() после добавления ролей и разрешений. В противном случае добавленные данные не будут обнаружены при добавлении RolePermissions с использованием ядра EF.

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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...