Класс выражения, замените логическое значение на сравнение строк - PullRequest
1 голос
/ 10 июля 2020

В нашей базе данных везде были логические значения IsActive в качестве мягкого удаления. У нас есть структура сущности, блокирующая все запросы с отключенным флагом. Недавно мы изменили базу данных, чтобы вместо флага IsActive иметь строку statusCode.

Как мне изменить приведенное ниже выражение, чтобы вместо этого проверить, есть ли StatusCode == "ACTIVE"

foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
  var isActiveProperty = entityType.FindProperty("IsActive");
  if (isActiveProperty != null && isActiveProperty.ClrType == typeof(bool))
  {
    var parameter = Expression.Parameter(entityType.ClrType, "p");
    var filter = Expression.Lambda(Expression.Property(parameter, isActiveProperty.PropertyInfo), parameter);
    entityType.QueryFilter = filter;
  }
}

Я пытался изменить типы на следующие, но это не работает. Лямбда, записанная таким образом, меня сбивает (длинная форма лямбда / параметра). Где-то мне нужно сравнить (isActivyProperty == "ACTIVE")

foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
    var isActiveProperty = entityType.FindProperty("StatusCode");
    if (isActiveProperty != null && isActiveProperty.ClrType == typeof(string))
    {
       var parameter = Expression.Parameter(entityType.ClrType, "p");
       var filter = Expression.Lambda(Expression.Property(parameter, isActiveProperty.PropertyInfo), parameter);
       entityType.QueryFilter = filter;//entityType.SetQueryFilter(filter);//Update for ef 3.0
    }
}

Ответы [ 2 ]

2 голосов
/ 10 июля 2020

Вы генерировали следующий код для каждого типа:

.QueryFilter = (p) => p.IsActive;

Теперь вы хотите

.QueryFilter = (p) => p.StatusCode == "ACTIVE";

Я считаю полезным написать выражение, которое я хочу, в C#, затем используйте отладчик, чтобы увидеть, как компилятор C# преобразовал это в граф выражений. Или просмотрите методы stati c в классе Expression и угадайте, что мне может понадобиться.

В вашем случае вам нужно, чтобы ваше лямбда-тело включало дополнительный тест на равенство и постоянное значение;

Expression.Equal(Expression.Property(...), Expression.Constant("ACTIVE"))

Но есть и другие способы использования компилятора C# для создания Expression, которое вы хотите. Например:

public interface HasStatus {
    StatusCode { get; set; }
}

public static void SetQueryFilter<T>(ModelBuilder builder) where T:HasStatus =>
    builder.Entity<T>().HasQueryFilter(p => p.StatusCode == "ACTIVE");

typeof(...).GetMethod("SetQueryFilter")
    .MakeGenericMethod(entityType.ClrType)
    .Invoke(null, new object[]{ builder });
1 голос
/ 10 июля 2020

Я думаю, вам нужно:

Expression.Lambda(Expression.Equal(Expression.Property(parameter, "StatusCode"),
    Expression.Constant("ACTIVE", typeof(string))), parameter);

Примечание: если FindProperty возвращает член, вы также можете использовать его в Expression.Property, чтобы избежать второго поиска отражения:

Expression.Lambda(Expression.Equal(Expression.Property(parameter, isActiveProperty),
    Expression.Constant("ACTIVE", typeof(string))), parameter);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...