c# - EF 中是否有针对 LINQ 表达式的等效语句?
问题描述
我有一种方法可以从特定聊天室获取未被阻止且不是自己的参与者。有没有办法将所有语句放在一个 DB 语句中,这是一种更优雅紧凑的解决方案?
Task<IList<ChatParticipant>> GetParticipants(int chatId, int excludeUserId)
{
var chatParticipants = await Context.ChatParticipant
.Include(x => x.Chat)
.Include(x => x.Participant)
.Where(c => c.ParticipantId != excludeUserId)
.ToListAsync();
var blockers = await Context.BlockedParticipant
.Include(x => x.Blocker)
.Where(c => c.BlockedId == excludeUserId)
.Select(x => x.Blocker)
.ToListAsync();
var result = chatParticipants.Where(p => blockers.All(p2 => p2.Id != p.ParticipantId)).ToList();
return result;
}
解决方案
虽然我同意将查询分开可以提高可读性,但另一个考虑是这两个查询将在过滤和分页等之前将所有各自的数据加载到内存中。这对服务器资源来说会很昂贵。对这段关系有所了解,您可以尝试以下方法:
Task<IList<ChatParticipant>> GetParticipants(int chatId, int excludeUserId)
{
var chatParticipants = await Context.ChatParticipant
.Include(x => x.Chat)
.Include(x => x.Participant)
.Where(c => c.ParticipantId != excludeUserId
&& !Context.BlockedParticipant.Any(b =>
b.BlockedId == excludeUserId && b.Blocker.Id == c.ParticipantId))
.ToListAsync();
return chatPaticipants;
}
我相信该方法也应该标记为async
便于await
和避免对 DbContext 的潜在多线程访问。我不是 100% 确定我已经捕获了阻止者和参与者之间的关系,但这是我可以从原始查询中推断出来的。将它们合并到单个查询中并不能提高可读性,但可以避免在分页之类的操作之前将较大的集合加载到内存中。
推荐阅读
- java - 为什么从创建列表的方法返回 unmodifiableList 更好?
- java - 优化推荐
- java - Spring Boot - 单元测试 Spring Data JPA 存储库
- javascript - 可以使用不存在的 url 进行 AJAX 调用吗?
- mysql - MYSQL 查询转换为 SQLSERVER
- jmeter - JMeter - 由于“执行 EVAL 超时”和 500 INTERNAL SERVAR ISSUE 而导致 350 个并发用户负载测试失败
- css - 中心有透明孔的 CSS 导航栏(新材料设计导航栏)
- sql - SQL 子类别总计未正确放置在每个父类别的末尾
- asp.net - 无法显示 ViewModel 的所有字段
- javascript - 从涉及承诺的函数返回非承诺值