JasperDaDolphin
JasperDaDolphin

Reputation: 334

How to seed data for entity with navigation property in EF Core?

I'm working with EF Core and I have a Role entity that owns a list of RolePermission. I'm using the IEntityTypeConfiguration<Role> interface to configure the entity.

While I am able to seed the Role data, I'm not sure how to seed the RolePermission data which is a navigation property.

Here's the Role configuration:

internal class RoleConfiguration : IEntityTypeConfiguration<Role>
{
    public void Configure(EntityTypeBuilder<Role> builder)
    {
        builder.HasKey(e => e.Id);

        builder.HasIndex(e => e.Name);

        builder.Property(e => e.Id)
               .HasConversion(id => id.Value, value => new RoleId(value));

        // Seed roles
        builder.HasData(DefaultRoleDefinition.DefaultRole);

        builder.OwnsMany(p => p.Permissions, navigationBuilder =>
        {
            navigationBuilder.HasKey(e => e.Id);

            navigationBuilder.WithOwner()
                             .HasForeignKey(e => e.RoleId);

            navigationBuilder.Property(e => e.Id)
                             .HasConversion(id => id.Value, value => new RolePermissionId(value));

            navigationBuilder.Property(e => e.RoleId)
                             .HasConversion(id => id.Value, value => new RoleId(value));

            navigationBuilder.Property(e => e.PermissionId)
                             .HasConversion(id => id.Value, value => new PermissionId(value));
        });

        // Should I be seeding the RolePermissions here...
    }
}

I also have a DefaultRoleDefinition class to define the default role and permissions:

public static class DefaultRoleDefinition
{
    public static RoleId DefaultRoleId = new RoleId(new Guid("7ac7a3d3-3b59-442d-a7e3-097888798212"));

    private static Role? _defaultRole;

    public static Role DefaultRole
    {
        get
        {
            if (_defaultRole == null)
            {
                _defaultRole = new Role(DefaultRoleId, "Default", "Default role for users.");
            }
            return _defaultRole;
        }
    }

    public static void InitializeDefaultRolePermissions()
    {
        var rolePermissions = new List<RolePermission>();

        rolePermissions.Add(new RolePermission(
            new RolePermissionId(new Guid("19aa8fe4-e2bd-4949-b12e-9f5f06a14850")),
            DefaultRole.Id,
            PermissionDefinitions.PermissionDictionaryName[Policies.Tenant.Create].Id
        ));

        DefaultRole.AddRange(rolePermissions);
    }
}

Should I be seeding the RolePermission data within the RoleConfiguration class? If so, how do I do it properly?

I have tried

.HasData(object[] data) 

after

OwnsMany(p => p.Permissions, xxx) 

but I get an error:

The seed entity for entity type 'Role' cannot be added because it has the navigation 'Permissions' set. To seed relationships, add the entity seed to 'RolePermission' and specify the foreign key values {'RoleId'}. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the involved property values.

Upvotes: 0

Views: 519

Answers (0)

Related Questions