使用三元表达式的损坏的 LINQ 查询



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

查看您的完整表达式,布尔逻辑的问题非常清楚。

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

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

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

其实是

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

结果是true

最新更新