具有三元表达式的LINQ查询损坏

时间:2019-06-10 21:31:32

标签: c# linq asp.net-core

我有这个查询来获取文章列表。如果是文章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 个答案:

答案 0 :(得分:2)

根据您编辑的问题,您遇到AND / OR优先级问题。您的AND / OR逻辑有问题。

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

实际上是

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

结果为true

答案 1 :(得分:2)

看看您的完整表达式,布尔逻辑很清楚这个问题。

(!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)