我有以下抽象类:
public abstract class Notification
{
public Notification()
{
this.receivedDate = DateTime.Now.ToUniversalTime();
}
public int Id { get; set; }
public DateTime receivedDate { get; set; }
public bool unread { get; set; }
public virtual ApplicationUser recipient { get; set; }
}
有几个类继承自它,例如ProfileViewNotification
和NewMessageNotification
:
public class ProfileViewNotification: Notification
{
public virtual ApplicationUser Viewer { get; set; }
}
public class NewMessageNotification: Notification
{
public virtual Message Message { get; set; }
}
我有以下方法在我的数据库中查询具有给定Notification
ApplicationUser
的所有recipient
:
public static List<NotificationApiViewModel> GetNotificationsForUser(string idOfUser)
{
List<NotificationApiViewModel> resultAsApiViewModel = new List<NotificationApiViewModel>();
List<ProfileViewNotification> ofProfileViewNotificationType = null;
List<NewMessageNotification> ofNewMessageNotificationType = null;
try
{
using (var context = new ApplicationDbContext())
{
var query = context.Notifications.Where(c => c.recipient.Id == idOfUser);
ofNewMessageNotificationType = query.OfType<NewMessageNotification>().Any() ?
query.OfType<NewMessageNotification>()
.Include(n => n.recipient)
.Include(n => n.recipient.MyProfile)
.Include(n => n.recipient.MyProfile.ProfileImages)
.Include(n => n.Message)
.Include(n => n.Message.Author)
.Include(n => n.Message.Author.MyProfile)
.Include(n => n.Message.Author.MyProfile.ProfileImages)
.Include(n => n.Message.Recipient)
.Include(n => n.Message.Recipient.MyProfile)
.Include(n => n.Message.Recipient.MyProfile.ProfileImages)
.ToList()
: null;
ofProfileViewNotificationType = query.OfType<ProfileViewNotification>().Any() ?
query.OfType<ProfileViewNotification>()
.Include(n => n.recipient)
.Include(n => n.recipient.MyProfile)
.Include(n => n.recipient.MyProfile.ProfileImages)
.Include(n => n.Viewer)
.Include(n => n.Viewer.MyProfile)
.Include(n => n.Viewer.MyProfile.ProfileImages)
.ToList()
: null;
}
}
catch (Exception ex)
{
//Log issue
}
if (ofNewMessageNotificationType != null)
{
foreach (var n in ofNewMessageNotificationType)
{
resultAsApiViewModel.Add(NotificationApiViewModel.ConvertToApiViewModel(n));
}
}
if (ofProfileViewNotificationType != null)
{
foreach (var n in ofProfileViewNotificationType)
{
resultAsApiViewModel.Add(NotificationApiViewModel.ConvertToApiViewModel(n));
}
}
return resultAsApiViewModel;
}
重要的是要注意,我的ConvertToApiViewModel
方法都没有查询数据库,这就是我在原始查询中拥有所有这些Include
的原因。此外,为简洁起见,上面仅包括两种类型的通知,但我总共有十几种。
我的问题是我的方法非常慢。对于只有20个通知的用户,需要一分钟才能完成!
任何人都可以告诉我我做错了什么?
答案 0 :(得分:0)
您正在为数据库中的每个查询打电话,所以您可以做的就是将它们组合成一个查询,如下所示:
try
{
using (var context = new ApplicationDbContext())
{
//Here you execute the single query
var query = context.Notifications.Where(c => c.recipient.Id == idOfUser)
.Include(n => n.recipient)
.Include(n => n.recipient.MyProfile)
.Include(n => n.recipient.MyProfile.ProfileImages)
.Include(n => n.Message)
.Include(n => n.Message.Author)
.Include(n => n.Message.Author.MyProfile)
.Include(n => n.Message.Author.MyProfile.ProfileImages)
.Include(n => n.Message.Recipient)
.Include(n => n.Message.Recipient.MyProfile)
.Include(n => n.Message.Recipient.MyProfile.ProfileImages)
.Include(n => n.Viewer)
.Include(n => n.Viewer.MyProfile)
.Include(n => n.Viewer.MyProfile.ProfileImages)
.ToList();
ofNewMessageNotificationType = query.OfType<NewMessageNotification>().Any() ?
query.OfType<NewMessageNotification>(): null;
ofProfileViewNotificationType = query.OfType<ProfileViewNotification>().Any() ?
query.OfType<ProfileViewNotification>() : null;
}
}
catch (Exception ex)
{
//Log issue
}
if (ofNewMessageNotificationType != null)
{
foreach (var n in ofNewMessageNotificationType)
{
resultAsApiViewModel.Add(NotificationApiViewModel.ConvertToApiViewModel(n));
}
}
if (ofProfileViewNotificationType != null)
{
foreach (var n in ofProfileViewNotificationType)
{
resultAsApiViewModel.Add(NotificationApiViewModel.ConvertToApiViewModel(n));
}
}
return resultAsApiViewModel;
}
希望这会有所帮助......
答案 1 :(得分:0)
感谢大家的意见和回复。为了记录我更快地查询的方式是使用query.Select(n => new DTO{})
和Data Transfer Objects (DTOs)而不是我的多个Include
。就这一点而言,我将性能提高了一个数量级。我还使查询异步,这进一步提高了性能。