Эф ядро ​​абстрактный HasQueryFilter от DbContext - PullRequest
0 голосов
/ 15 октября 2019

Я пытаюсь создать общий тип авторизации поверх DbContext, чтобы моим разработчикам не нужно было заботиться об авторизации в репозитории / домене.

Простой пример, такой как

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>().Property<string>("TenantId").HasField("_tenantId");

    // Configure entity filters
    modelBuilder.Entity<Blog>().HasQueryFilter(b => EF.Property<string>(b, "TenantId") == _tenantId);
    modelBuilder.Entity<Post>().HasQueryFilter(p => !p.IsDeleted);
}

Какой пример MS работает. _tenantId будет использоваться для создания выражения, и для каждого экземпляра DbContext будет использоваться правильное значение _tenantId.

Но я не хочу, чтобы все наши авторизаторы были настроены из контекста нашей БД, я хочу внедрить его. Что-то вроде

public class AgreementAuthorization : IEntityAuthorization
{
    private readonly string _legalEntityNumber;

    public AgreementAuthorization(IAuthScope scope)
    {
        _legalEntityNumber = scope.LegalEntityNumber;
    }

    public void Build(ModelBuilder builder)
    {
        builder
            .Entity<Agreement>()
            .HasQueryFilter(a => _legalEntityNumber == null || a.LegalEntity.Number == _legalEntityNumber);
    }
}

public class MyDbContext : DbContext 
{
   private IEnumerable<IEntityAuthorization> _entityAuthorization;

   MyDbContext(IEnumerable<IEntityAuthorization> entityAuthorization) 
   {
      _entityAuthorization = entityAuthorization;
   }

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

        _entityAuthorization.ForEach(a => a.Build(builder));
    }
}

Это не работает, каждый раз запрашивать тест на нуль и проходить. Если я переместу код непосредственно в DbContext, он будет работать. Значение _entityAuthorization лежит непосредственно на DbContext.

1 Ответ

0 голосов
/ 16 октября 2019

С https://docs.microsoft.com/en-us/ef/core/querying/filters

Фильтры не могут содержать ссылки на свойства навигации.

Вы ссылаетесь на свойство навигации LegalEntity.

И этоможет потенциально повлиять на вас, а также на то, что вы передаете IEnumerable<IEntityAuthorization>:

В настоящее время невозможно определить несколько фильтров запросов для одной и той же сущности - будет применен только последний. Тем не менее, вы можете определить один фильтр с несколькими условиями, используя логический оператор AND (&& в C #).

Обновление:

Тогда я думаю, что вам нужно сослаться наПоле / свойство MyDbContext напрямую, а не внутри другого объекта. Введите класс / интерфейс, который дает доступ к значениям, по которым следует фильтровать, затем настройте фильтры в конце метода OnModelCreating. Вы можете взаимодействовать с конфигурациями сущностей и их свойствами, чтобы применять требуемые фильтры на основе наличия применимого свойства.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...