Установите значение перед сохранением - PullRequest
0 голосов
/ 23 октября 2018

Мне было интересно, есть ли какой-нибудь способ установить значение на объекте?Поскольку я работаю над многопользовательским веб-приложением, и я хотел бы установить текущий идентификатор арендатора (через простую службу DI).

Я пытался использовать HasDefaultValue() в Fluent API, однако при этом попытаетсяпреобразовать в функцию SQL.Так что это не работает для меня.

builder.Entity<Order>( )
    .HasQueryFilter(p => p.TenantId == _tenantProvider.GetTenantId())
    .Property(p => p.TenantId)
    .HasDefaultValue(_tenantProvider.GetTenantId());

Любые предложения с благодарностью.

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

EF Core генерация значения при добавлении с пользовательским ValueGenerator

Создает значения для свойств при добавлении объекта в контекст.

может использоваться для присвоения TenantId новым объектам.Внутри метода Next вы можете получить TenantId из контекста (или некоторого сервиса).

Взяв ваш пример, генератор значений может быть вложенным классом внутри вашего DbContext, например так:

class TenantIdValueGenerator : ValueGenerator<int>
{
    public override bool GeneratesTemporaryValues => false;
    public override int Next(EntityEntry entry) => GetTenantId(entry.Context);
    int GetTenantId(DbContext context) => ((YourDbContext)context)._tenantProvider.GetTenantId();
}

Все, что вам нужно, - это назначить генератор для свойства TenantId, используя некоторые из HasValueGenerator свободный API.

Единственная проблема заключается в том, что при проектировании значениягенераторы вызываются, только если свойство не имеет явно установленного значения (для свойства int - если значение равно 0).

Так что лучше подходить к абстрагированию (и полному контролю) TenantId свойство, удалив его из моделей сущностей и заменив его теневым свойством .

Следовательно, я предлагаю удалить TenantId из классов сущностей и вызвать следующий метод внутри вашего OnModelCreating для каждой сущности, которой требуется столбец TenantId:

void ConfigureTenant<TEntity>(ModelBuilder modelBuilder) where TEntity : class
{
    modelBuilder.Entity<TEntity>(builder =>
    {
        builder.Property<int>("TenantId")
            .HasValueGenerator<TenantIdValueGenerator>();

        builder.HasQueryFilter(e => EF.Property<int>(e, "TenantId") == _tenantProvider.GetTenantId());
    });
}
0 голосов
/ 23 октября 2018

Вы можете переопределить метод DbContext.SaveChanges () и выполнить итерации в записях ChangeTracker:

public override int SaveChanges()
{
    foreach (var entityEntry in ChangeTracker.Entries()) // Iterate all made changes
    {
        if (entityEntry.Entity is Order order)
        {
            if (entityEntry.State == EntityState.Added) // If you want to update TenantId when Order is added
            {
                order.TenantId = _tenantProvider.GetTenantId();
            }
            else if (entityEntry.State == EntityState.Modified) // If you want to update TenantId when Order is modified
            {
                order.TenantId = _tenantProvider.GetTenantId();
            }
        }
    }
    return base.SaveChanges();
}

Конечно, для этого необходимо, чтобы поставщик клиента был внедрен в ваш контекст.

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