Доступ к заявкам на удостоверения через Entity Framework (с проекцией Automapper и PredicateBuilder) - PullRequest
0 голосов
/ 22 ноября 2018

Похоже, я пытаюсь достичь невозможного: из (вычисляемого) свойства моей сущности (сущности) я пытаюсь проверить, есть ли у вошедшего в систему пользователя определенная претензия.Если быть более точным, он не работает при попытке использовать это свойство из запроса БД Linq.

Запрос Linq не является чем-то особенным:

var query = DbContext.Organizations.Where(x => !x.DeleteDate.HasValue);

Поиск данных инициируется проекция автомата :

var dto = await query.ProjectToListAsync<MyDto>(Mapper.ConfigurationProvider);

Я добавил это свойство в свой объект организации:

[Computed]
public bool CanCancel => !CancelDate.HasValue 
                             && identity.Claims.Any(c => c.Type == permission.ToString());  // identity is of type ClaimsIdentity, permission is an enum from our project

( Вычислено Атрибут происходит из библиотеки DelegateCompiler , которая позволяет декомпилировать делегат или тело метода в его лямбда-представление. Если вы пометите метод вашей сущности этим, Automapper может использовать его в запросе во время проецирования.В нашем проекте мы часто используем эту технику, она очень полезна!)

К сожалению, это не похоже на ClaimsIdentity.Claims можно декомпилировать.При выполнении кода выдается ошибка :

Невозможно создать постоянное значение типа 'System.Security.Claims.Claim'.В этом контексте поддерживаются только примитивные типы или типы перечисления.

Я полагаю, что это как-то связано с внутренностями этого утверждения:

public virtual IEnumerable<Claim> Claims
{
  get
  {
    for (int i = 0; i < this.m_instanceClaims.Count; ++i)
      yield return this.m_instanceClaims[i];
    if (this.m_externalClaims != null)
    {
      for (int j = 0; j < this.m_externalClaims.Count; ++j)
      {
        if (this.m_externalClaims[j] != null)
        {
          foreach (Claim claim in this.m_externalClaims[j])
            yield return claim;
        }
      }
    }
  }
}

Но я не вижукак я мог решить это.У кого-нибудь есть идея?

Заранее спасибо!

1 Ответ

0 голосов
/ 10 декабря 2018

Хорошо, я не нашел идеального решения этой проблемы, но мне удалось обойти ее, путем:

a) создания статического свойства, которое проверяет утверждение:

private static bool CanCancel => identity.HasPermission(AppPermission.CanCancel);

(HasPermission - это метод расширения, использующий метод HasClaim для ClaimsIdentity для проверки того, что удостоверение имеет данное разрешение)

b) доступ к этим свойствам из моего вычисляемого свойства:

[Computed] 
public bool IsCancelable => !CancelDate.HasValue && CanCancel;

Поскольку это свойство больше не содержит входную переменную (например, разрешение на проверку), теперь Linq to Entities может правильно преобразовать его в запрос.

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