Entity Framework, где пункт для вычисляемого свойства - PullRequest
0 голосов
/ 05 июня 2018

У меня есть следующая модель:

public class Account
{
    public Guid Id{ get; set; }

    [Filterable]
    public string Code{ get; set; }

    [Filterable]
    public string AccountStatus { get; set; }
}

значение свойства AccountStatus рассчитывается на основе значений StartDate и EndDate, поэтому в моем запросе Linq в моем репозитории IИмеем следующее:

public IEnumerable<Account> Get(QueryClause<Account> queryClause, out ForGetCollectionOptions forGetCollectionOptions)
{
        using (_dbContext)
        {
            var result = (
              from account in _dbContext.Accounts
              select new Account
              {
               Id = account.ID,
               Code = account.Code.Trim(),
               AccountStatus = StatusCalculator.GetStatus(account.StartDate, account.EndDate)
               }
           ApplyFilterClause(ref result, queryClause.FilterClause);
        }
}

для расчета статуса счета. Имеется следующее: public enum Status {Неактивно, Активно, Будущее}

public static class StatusCalculator
{
    public static string GetStatus(DateTime? startDate, DateTime? endDate)
    {
        var now = DateTime.Now;

        if (startDate != null && startDate > now)
        {
            return Status.Future.ToString().ToLower();
        }

        if (startDate != null && endDate == null)
        {
            return Status.Active.ToString().ToLower();
        }

        return Status.Inactive.ToString().ToLower();
    }
}

Проблема в том, что при попыткеотфильтровывая accountStatus, например, «неактивный», я получаю следующее предупреждение во время выполнения:

warn: Microsoft.EntityFrameworkCore.Query[20500]
  The LINQ expression 'where (GetStatus([account].StartDate, [account].EndDate) == "inactive")' could not be translated and will be evaluated locally.
 warn: Microsoft.EntityFrameworkCore.Query[20500]
  The LINQ expression 'Count()' could not be translated and will be evaluated locally.

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

Как добавить пользовательский перевод для этого свойства для предложения where, а также сортировать и считать?

1 Ответ

0 голосов
/ 05 июня 2018

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

public IEnumerable<Account> Get(QueryClause<Account> queryClause, out ForGetCollectionOptions forGetCollectionOptions)
{
        using (_dbContext)
        {
            var result = (
              from account in _dbContext.Accounts
              select new Account
              {
               Id = account.ID,
               Code = account.Code.Trim(),
               AccountStatus = (account.StartDate != null && account.EndDate == null)
                                  ? "Active"
                                  : (account.StartDate != null && account.StartDate > DateTime.Now) 
                                     ? "Future"
                                     : "Inactive"
               }
           ApplyFilterClause(ref result, queryClause.FilterClause);
        }
}

Это должно позволить EF преобразовать это в оператор CASE, например:

SELECT  foo
       ,(CASE 
          WHEN t.StartDate IS NOT NULL...
          WHEN t.StartDate IS NOT NULL AND t.StartDate > GetDate()
          ELSE ...
        )
FROM bar
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...