EF Core: How to add a column to all indexes for entities

Viewed 28

I have a SaaS application where I am defining entities that will implement an ITenantAwareEntity interface like so:

/// <summary>
/// Entities that implement this interface will be restricted to writing to and reading from
/// their assigned tenant only.
/// </summary>
public interface ITenantAwareEntity
{
    /// <summary>
    /// The tenant this entity belongs to.
    /// </summary>
    Guid TenantId { get; set; }
}

In my OnModelCreating method for the database context, I have code that will identify these entities and apply a global filter on the tenant id to ensure tenants are isolated.

I also want to examine all indexes for these tables to see if the TenantId is the first column in the index (or if there at all).

Personally, I'd prefer to just inject the TenantId column as the first column of the index, but the EF model has these as readonly properties, so... delete the old and replace with the original with an extra column, right? Not so easy to do.

I tried something like this:

//ensure that all indexes for the tenant-aware entity reference the tenant ID
var indexes = entityType.GetIndexes().ToList();
foreach (var index in indexes)
    if (index.Properties.All(i => i.Name != nameof(ITenantAwareEntity.TenantId)))
    {
        //make the tenant id the first column in the index.
        var props = new List<IMutableProperty>
            { entityTypeBuilder.Property(nameof(ITenantAwareEntity.TenantId)).Metadata };
        props.AddRange(index.Properties);
        entityType.AddIndex(props);
    }

foreach (var index in indexes)
{
    //with a new index created with the tenant id, remove the old index.
    entityType.RemoveIndex(index);
}

I split up creating the index and removing the index since I got yelled at for trying to change a collection while it was enumerated, but now I get a message like:

The index {'TenantId'} cannot be removed from the entity type 'MyEntity' because it is defined on the entity type 'MyEntity'.

...so I guess I'm still doing this wrong.

How do I remove/ replace an index while building the model, or failing that (preferably) just add a column to the front of the index?

0 Answers
Related