Сломанный запрос LINQ с троичным выражением - PullRequest
0 голосов
/ 11 июня 2019

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

List<Article> articles = await db
    .Articles
    .Where(a => a.IsLocked
        ? a.CreatedBy.Id == LoggedInAdminUserId
        : true)
    .ToListAsync();

Но, как и сейчас, любой авторизованный администратор может видеть все заблокированные.статьи, независимо от того, кто их создал.

Как мне изменить мой запрос?

** РЕДАКТИРОВАТЬ **

Приведенный выше запрос является сокращенной версией.Вот полный запрос:

List<Article> dbm = await db.Articles
    .Where(s => 
        (!s.IsLocked || s.CreatedBy.Id == LoggedInAdminUserId) &&
        s.Title.Contains(search) ||
        s.PreTitle.Contains(search) ||
        s.Preamble.Contains(search) ||
        s.MainText.Contains(search) ||
        s.CreatedBy.Member.FirstName.Contains(search) ||
        s.CreatedBy.Member.LastName.Contains(search) ||
        s.EditedBy.Member.FirstName.Contains(search) ||
        s.EditedBy.Member.LastName.Contains(search) ||
        s.FrontPageItem.PublishedBy.Member.FirstName.Contains(search) ||
        s.FrontPageItem.PublishedBy.Member.LastName.Contains(search)
    )
    .Include(f => f.FrontPageItem)
    .Include(e => e.CreatedBy)
        .ThenInclude(m => m.Member)
    .Include(e => e.EditedBy)
        .ThenInclude(m => m.Member)
    .Include(p => p.PublishReadyBy)
        .ThenInclude(m => m.Member)
    .Include(o => o.ArticleOperations)
    .OrderByDescending(s => s.DateCreated)
    .ToListAsync();

РЕДАКТИРОВАТЬ 2

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

.Where(s => 
    (!s.IsLocked || s.CreatedBy.MemberId == AdminUserMemberId) &&
    (s.Title.Contains(search) ||
    s.PreTitle.Contains(search) ||
    s.Preamble.Contains(search) ||
    s.MainText.Contains(search) ||
    s.CreatedBy.Member.FirstName.Contains(search) ||
    s.CreatedBy.Member.LastName.Contains(search) ||
    s.EditedBy.Member.FirstName.Contains(search) ||
    s.EditedBy.Member.LastName.Contains(search) ||
    s.FrontPageItem.PublishedBy.Member.FirstName.Contains(search) ||
    s.FrontPageItem.PublishedBy.Member.LastName.Contains(search))
)

Ответы [ 2 ]

2 голосов
/ 11 июня 2019

Глядя на ваше полное выражение, проблема довольно ясна с логической логикой.

(!s.IsLocked || s.CreatedBy.Id == LoggedInAdminUserId) &&
s.Title.Contains(search) ||
s.PreTitle.Contains(search) ||
... more

Вы проверяете, разблокирована ли статья или пользователь является создателем / администратором, а затем игнорируете этот результат.для первого положительного ответа от всех ваших OR выражений.

Решение заключается в использовании круглых скобок, например:

(!s.IsLocked || s.CreatedBy.Id == LoggedInAdminUserId) &&
(s.Title.Contains(search) ||
s.PreTitle.Contains(search) ||
... more)
2 голосов
/ 11 июня 2019

Согласно вашему отредактированному вопросу, у вас есть проблема И / ИЛИ Приоритета.У вашей логики AND / OR есть проблемы.

false && true || false || true || ....

на самом деле

(false && true) || false || true || ...

, что приводит к true

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