Возможно ли реализовать авторизованный DbContext? - PullRequest
0 голосов
/ 24 апреля 2020

При наличии DbContext и ClientContext (пользовательских данных сеанса о пользователе) возможно ли создать DbContext, который «авторизован»: где доступно только подмножество строк в каждой «таблице»?

С авторизованным DbContext я пытаюсь получить централизованную реализацию авторизации на уровне строк.

Я немного ее исследовал, и единственный способ отфильтровать DbSet был бы использовать что-то вроде Queryable.Where, но это возвращает IQueryable<T>, и, похоже, нет способа вернуть отфильтрованный DbSet<T> (за исключением, может быть, глобальных запросов, которые вы можете настроить в Startup, но они этого не делают иметь доступ к внедренным зависимостям, таким как ClientContext).

Можно ли определить DbSet<T> фильтры авторизации через внедренную зависимую область, такую ​​как ClientContext?

Ответы [ 2 ]

2 голосов
/ 24 апреля 2020

Существуют фильтры запросов на уровне модели: https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-2.0#model -level-query-filters

По ссылке:

Эта функция разрешает запрос LINQ. предикаты (логическое выражение, обычно передаваемое оператору запроса LINQ Where), которые должны быть определены непосредственно в типах объектов в модели метаданных (обычно в OnModelCreating). Такие фильтры автоматически применяются к любым запросам LINQ, включающим эти типы объектов, включая типы объектов, на которые ссылаются косвенно, например, с помощью ссылок на свойства «Включить» или «Прямая навигация».

Пример по ссылке:

public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    public int TenantId { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>().HasQueryFilter(
            p => !p.IsDeleted
            && p.TenantId == this.TenantId);
    }
}

Вы можете использовать это для простого сценария ios. Вы определяете свойство экземпляра в своем DbContext, а в OnModelCreating вы указываете HasQueryFilter для любой сущности, которую хотите фильтровать. Свойство является свойством экземпляра, поэтому, если у вас есть DbContext в области, будет использовано правильное значение свойства из этого запроса, что удобно, если вы хотите что-то фильтровать из вашего UserContext. Лично я никогда не пробовал этого, так что я не знаю, насколько это сложно для реализации, но вы можете поиграть с этим.

0 голосов
/ 24 апреля 2020

Я не уверен насчет ядра EF и EF, но мы абстрагируем DbContext в функциональные блоки c 'logi c'.

Например:

class DbContext()
{
   public DbSet<PeopleEntity> peoples;
}
class PeopleLogic()
{
   DbContext _context;

   PeopleLogic(DbContext context)
   {
       _context = context;
   }

   IEnumerable GetAllPeoples()
   {
      // create context,
      // apply filters
      // return result
   }
}

У нас, конечно, есть база для простых операций CRUD;

public void AddOrUpdate(){
            lock (SyncDatabaseWriteObject)
            {
                try
                {
                    using (var context = CreateContext())
                    {
                        //insert the entity and add it to the db context
                        context.Set<TEntity>().AddOrUpdate((TEntity)entity);
                        context.SaveChanges();
                    }

                    return entity;
                }
                catch (Exception ex)
                {
                    throw new DatabaseAccessException("Error occured while getting saving.", ex);
                }
            }
}

И вместо передачи контекста db, мы обходим вокруг логики.

например, мы разделяем логики c для базы данных и доступ к базе данных на 2 отдельных проекта, тогда бизнес-уровень использует только уровень dbAccess.

...