我知道这是一个旧帖子,但我仍然想为寻找相同解决方案的人发布一些改进意见。
1. 网络冗余
选择 Ids 然后运行查询以加载具有 Ids 的项目是多余的,可以通过简单地运行以下操作来实现相同的效果
解决方案:
var userNotifications = _context.Notifications
.OrderByDescending(n => n.DateTime)
.Skip(offset)
.Take(limit)
.OfType<NotificationUser>()
.Include(n => n.TargetUser)
.Include(n => n.TargetUser.Images)
.ToList();
这样,您不需要等待2个数据库连接,只需要一个。此外,您还可以节省一些流量。
2. 忽略实体分页?
人们可能会认为,该特定方法仅用于查看继承类型的实体,因此我期望Skip和Take直接在该类型的实体上工作。例如,我想跳过10个NotificationUsers,而不是10个用户(其中仅有4个是NotificationUsers)。
解决方案:将ofType移动到查询的更高位置。
var userNotifications = _context.Notifications
.OfType<NotificationUser>()
.OrderByDescending(n => n.DateTime)
.Skip(offset)
.Take(limit)
.Include(n => n.TargetUser)
.Include(n => n.TargetUser.Images)
.ToList();
3. 异步/等待
在编写API时,应考虑使用异步/等待,因为它不会阻塞线程,从而浪费更少的资源(如果您尚未使用它,则可能需要重写大量现有代码)。
请仔细研究异步/等待的优点,并在等待结果等场景中使用它们。
解决方案:更改为:
private List<NotificationUser> GetNotificationUsers(int offset, int limit)
{
return _context.Notifications
.OfType<NotificationUser>()
.OrderByDescending(n => n.DateTime)
.Skip(offset)
.Take(limit)
.Include(n => n.TargetUser)
.Include(n => n.TargetUser.Images)
.ToList();
}
转化为这样
private async Task<List<NotificationUser>> GetNotificationUsersAsync(int offset, int limit)
{
return await _context.Notifications
.OfType<NotificationUser>()
.OrderByDescending(n => n.DateTime)
.Skip(offset)
.Take(limit)
.Include(n => n.TargetUser)
.Include(n => n.TargetUser.Images)
.ToListAsync();
}
注意:
你需要修改使用此方法的任何位置,从
开始。
var x = GetNotificationUsers(skip, take)
为了
var x = await GetNotificationUsersAsync(skip, take);
并将该方法改为异步方法,同时返回一个任务(task)。
TargetUser
),然后尝试将检索到的实体转换为不包含该属性的类型。因此,它确实会抛出异常,在这种情况下是正常行为。 - paradise