I have the following abstract class:
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; }
}
Several classes inherit from it, for instance ProfileViewNotification
and NewMessageNotification
:
public class ProfileViewNotification: Notification
{
public virtual ApplicationUser Viewer { get; set; }
}
public class NewMessageNotification: Notification
{
public virtual Message Message { get; set; }
}
I have the following method to query my DB for all the Notification
with a given ApplicationUser
as a 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;
}
Important to note, none of my ConvertToApiViewModel
methods query the DB, that's why I have all these Include
in the original query. Also the above only includes 2 types of notifications for the sake of brevity but I have a dozen in total.
My problem is that my method is extremely slow. For a user who has a mere 20 notifications it takes over a minute to complete!
Anyone can tell me what I am doing wrong?