O filtro de consulta do EF Core 2.0.0 é armazenado em cache TenantId (atualizado para 2.0.1 ou superior)
Estou criando um aplicativo para vários inquilinos e estou tendo dificuldades com o que eu acho que é o EF Core que armazena em cache o ID do inquilino nas solicitações. A única coisa que parece ajudar é reconstruir constantemente o aplicativo à medida que entro e saio dos inquilinos.
Eu pensei que pode ter algo a ver com oIHttpContextAccessor
Por exemplo, sendo um singleton, mas não pode ser definido como escopo, e quando entro e saio sem reconstruir posso ver o nome do inquilino mudar na parte superior da página, por isso não é o problema.
A única outra coisa em que consigo pensar é que o EF Core está fazendo algum tipo de cache de consulta. Não sei por que seria uma instância com escopo definido e deveria ser reconstruída a cada solicitação, a menos que eu esteja errado, o que provavelmente estou. Eu esperava que ele se comportasse como uma instância com escopo definido para que eu pudesse simplesmente injetar o ID do inquilino no tempo de criação do modelo em cada instância.
Eu realmente apreciaria se alguém pudesse me apontar na direção certa. Aqui está o meu código atual:
TenantProvider.cs
public sealed class TenantProvider :
ITenantProvider {
private readonly IHttpContextAccessor _accessor;
public TenantProvider(
IHttpContextAccessor accessor) {
_accessor = accessor;
}
public int GetId() {
return _accessor.HttpContext.User.GetTenantId();
}
}
... que é injetado noTenantEntityConfigurationBase.cs onde eu o uso para configurar um filtro de consulta global.
internal abstract class TenantEntityConfigurationBase<TEntity, TKey> :
EntityConfigurationBase<TEntity, TKey>
where TEntity : TenantEntityBase<TKey>
where TKey : IEquatable<TKey> {
protected readonly ITenantProvider TenantProvider;
protected TenantEntityConfigurationBase(
string table,
string schema,
ITenantProvider tenantProvider) :
base(table, schema) {
TenantProvider = tenantProvider;
}
protected override void ConfigureFilters(
EntityTypeBuilder<TEntity> builder) {
base.ConfigureFilters(builder);
builder.HasQueryFilter(
e => e.TenantId == TenantProvider.GetId());
}
protected override void ConfigureRelationships(
EntityTypeBuilder<TEntity> builder) {
base.ConfigureRelationships(builder);
builder.HasOne(
t => t.Tenant).WithMany().HasForeignKey(
k => k.TenantId);
}
}
... que é herdado por todas as outras configurações de entidade inquilina. Infelizmente, não parece funcionar como eu havia planejado.
Eu verifiquei que o ID do inquilino que está sendo retornado pelo principal do usuário está mudando dependendo do usuário do inquilino que está conectado, portanto, esse não é o problema. Agradecemos antecipadamente por qualquer ajuda!
Atualizar
Para uma solução ao usar o EF Core 2.0.1+, observe a resposta não aceita de mim.
Atualização 2
Observe também a atualização do Ivan para a versão 2.0.1+, que procura na expressão de filtro do DbContext que restaura a capacidade de defini-la uma vez em uma classe de configuração básica. Ambas as soluções têm seus prós e contras. Optei pelo Ivan's novamente, porque só quero aproveitar minhas configurações básicas o máximo possível.