EF Core Global Filter запроса на основе нулевой собственности, приводящего к NullReferenceExceptionC#

Место общения программистов C#
Ответить
Anonymous
 EF Core Global Filter запроса на основе нулевой собственности, приводящего к NullReferenceException

Сообщение Anonymous »

public partial class AppDbContext(DbContextOptions options, ILegalEntityProvider legalEntityProvider) : DbContext(options)
{
public Guid? LegalEntityId { get; } = legalEntityProvider.LegalEntity;

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);

// Apply a global query filter to all entities implementing IMultiLegalEntity.
// This ensures that queries only return records associated with the current LegalEntityId,
// which is determined from the 'extension_LegalEntityId' claim in the user's identity.
// The LegalEntityId is retrieved through the LegalEntityProvider, and only records with
// matching LegalEntityIds will be included in the query results.

// Global query filters are compiled and cannot be “switched off” on the fly unless you design them to be conditional.
modelBuilder.SetQueryFilterOnAllEntities(
x => LegalEntityId.HasValue && x.LegalEntities.Any(le => le.Id == LegalEntityId.Value)
);
}
}

Я использую EF Core Global Filters для фильтров для фильтрации записей на основе LegaletityId . По сути, если в токене JWT есть LegalentityID, фильтр гарантирует, что возвращаются только записи, связанные с текущим LegatentityID. LegalentityID извлекается у поставщика и применяется в глобальном фильтре запроса, как указано выше. Поскольку глобальные фильтры запросов в EF Core собираются один раз во время запуска, они не динамически приспосабливаются к изменениям стоимости LegalentityID во время выполнения. Это происходит потому, что фильтр оценивается при создании модели и остается статичным для последующих запросов. Я не мог придумать решения. Есть идеи, как справиться с этим?public static class ModelBuilderExtensions
{
///
/// Applies a global query filter to all entities of the specified type in the .
///
/// The type of the entity to which the filter will be applied. It must be a class type or interface type.
/// The instance to which the global filter will be applied.
/// An representing the filter to be applied to the entities.
/// The instance with the global query filter applied.
///
/// This method applies the specified filter to all entities that are assignable to the type.
/// If an entity already has a query filter, the new filter is combined with the existing filter using an AND operation.
///
public static ModelBuilder SetQueryFilterOnAllEntities(
this ModelBuilder builder,
Expression filter)
{
// Entities that are assignable to the TEntity generic
var entities = builder.Model.GetEntityTypes()
.Where(entity => typeof(TEntity).IsAssignableFrom(entity.ClrType))
.ToList();

foreach (var entity in entities)
{
// Creating a ParameterExpression with the actual type of the current entity
var entityParam = Expression.Parameter(entity.ClrType, "entity");

// Replacing the parameter with the actual entity parameter / (e.g => (entityParameter => ....))
var filterBody = ReplacingExpressionVisitor.Replace(filter.Parameters[0], entityParam, filter.Body);

// Getting the current query filters of the actual entity
var existingFilter = entity.GetQueryFilter();

if (existingFilter is not null)
{
// Other filter already present, combine them
filterBody = ReplacingExpressionVisitor.Replace(entityParam, existingFilter.Parameters[0], filterBody);
filterBody = Expression.AndAlso(existingFilter.Body, filterBody);

// Create a new lambda expression for the combined filter
existingFilter = Expression.Lambda(filterBody, existingFilter.Parameters);
}
else
{
// Create a new lambda expression for the current filter
existingFilter = Expression.Lambda(filterBody, entityParam);
}

// Setting the query filter to the entity
entity.SetQueryFilter(existingFilter);
}

return builder;
}
}


Подробнее здесь: https://stackoverflow.com/questions/794 ... llreferenc
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»