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

时间:2018-05-07 22:06:14

标签: c# linq entity-framework-core

我在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();

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

3 个答案:

答案 0 :(得分:2)

您要找的是All

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

答案 1 :(得分: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发送内存列表然后加入它的能力。

答案 2 :(得分:0)

假定您具有名称为“ 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