检查 ID 列表是否有效的更好方法(EF Core)

问题描述 投票:0回答:4

我在 html 页面中有一个复选框元素列表,所有元素都可选且具有不同的 ID,其 ID 通过 HTTP POST 发送到我的 API。为了安全起见,我需要检查发送的 ID 是否无效。它只是一个方法,如果我的数据库中不存在任何这些 ID,则返回 false;如果所有这些 ID 都存在,则返回 true。

最初看起来很简单,但我没有找到直接使用 EF Core 从数据库返回结果的方法。我总是需要将查询结果的

Count
与我的列表
Count
进行比较。

我更好的方法是:

public async Task<bool> IsIdListValid(IEnumerable<int> idList) =>
   (await _context.Foo
              .Select(x => x.Id)
              .CountAsync(id => idList.Contains(id))
   ) == idList.Distinct().Count();

所以,我要问的是:有更好的方法来编写该查询,更具可读性和性能吗?

c# linq entity-framework-core
4个回答
8
投票

您要找的是

All
:

public async Task<bool> IsIdListValid(IEnumerable<int> idList)  
{
   var validIds = await _context.Foo.Select(x => x.Id).ToListAsync();
   return idList.All(x => validIds.Contains(x));
}

4
投票

假设您有名为“idsLst”的 id 列表,因此您将从 db 获取所有匹配的 id,然后将从 db 返回的 id 列表与您的列表进行比较(如果它们相同),因此所有列表项都存在于 db 中,如果有差异,这意味着您有一些无效的 ID

var validIds = DbContext
    .UREntity
    .Where(x => idsLst.Contains(x.Id))
    .Select(x => x.Id);
    

var invalidIdsLst = ids.Except(validIds);

return invalidIdsLst.Count == 0; // return true if all valid

0
投票

您可以直接实现您的问题,而不是通过计数来验证:

public async Task<bool> IsIdListValid(IEnumerable<int> idList) =>
    idList.Any(id => !_context.Foo.Any(f => f.id == id));

这将在有效时向

idList
的每个成员发送 SQL 查询。如果
idList
很短,这可能没问题,否则您的
Count
查询可能是最好的,尽管不需要
Select
。但是,如果
idList
包含无效成员,这将是快捷方式,并在第一个无效成员处停止。

另一种可能性是使用 EntityFrameworkCore.MemoryJoin 扩展,该扩展添加了使用 SQL

VALUES
发送内存列表然后加入其中的功能。


0
投票

改进Mohamed Magdi的答案。

    var validIds = DbContext.UREntity
                            .Where(x => inputIdsLst.Contains(x.Id))
                            .Select(x => x.Id)
                            .ToListAsync();

    return inputIdsLst.Count == validIds.Count;

这里,我们只是比较两个列表的长度,以确定来自

inputIdsLst
的所有 id 是否都存在于表中。

var invalidIdsLst = inputIdsLst.Except(validIds);

如果我们使用

Except
,它将迭代
inputIdsLst

© www.soinside.com 2019 - 2024. All rights reserved.