Glimpse shows Duplicate EF queries

2019-06-25 14:04发布

问题:

I'm having problems with my MVC 4 application running too slowly. I installed Glimpse to profile the application. I think I've found part of the problem: many of my EF queries appear to be running twice! Here's my HomeController that is pulling some alerts:

[HttpGet]
    public virtual ActionResult Index()
    {
        var reportStart = DateTime.Today;
        var reportEnd = DateTime.Today.AddMonths(1);

        var query = _tameUow.Alerts
                            .FindBy(a => a.ApprovalStatusId == (int)AlertApprovalStatusCodes.Approved &&
                                    (a.ScheduledStartDateTime >= reportStart &&
                                     a.ScheduledStartDateTime <= reportEnd), a => a.SubmittedBy, a => a.ApprovalManager, a => a.ApprovalStatus);

        var model = ListAlertsViewModelBuilder.Build(query, null, false, false, false, false);

        model.RequiredViewData = new RequiredViewDataModel("Upcoming Alerts", "These are the upcoming active alerts for the next month.", "Home");
        return View(model);
    }

But when I view the SQL tab in glimpse, it shows the query twice! At first I thought it was just a bug and the same query was being displayed twice, but they have different execution times, so I think that the query is actually being run twice! Also, the little yellow exclamation mark shows up as a warning. I THINK this is warning me that it is a duplicate query...

http://i.imgur.com/jizQwKz.png What's going on here? I see this on all the pages I've tested, I chose this one as an example because it is the simplest. I tried setting a breakpoint on the query, and it is only being hit once.

Here's the VMBuilder:

public static class ListAlertsViewModelBuilder
{
    public static ListAlertsViewModel Build
        (IQueryable<Alert> query
        , string curUserExtId
        , bool showSubmittedDateTime
        , bool showStatus
        , bool showActions
        , bool showOwners)
    {
        var model = new ListAlertsViewModel();

        var alerts = query.Select(a => new AlertDetailsViewModel() {
            AlertId = (int)a.AlertId,
            ApprovalManager = a.ApprovalManager,
            ApprovalManagerExtId = a.ApprovalManagerExtId,
            ApprovalStatus = a.ApprovalStatus,
            ApprovalStatusId = (int)a.ApprovalStatusId,
            Building = a.Building,
            Cause = a.Cause,
            //Comments = a.Comments,
            Impact = a.Impact,
            ScheduledEndDateTime = a.ScheduledEndDateTime,
            ScheduledStartDateTime = a.ScheduledStartDateTime,
            Service = a.Service,
            SubmittedBy = a.SubmittedBy,
            SubmittedByExtId = a.SubmittedByExtId,
            SubmittedDateTime = a.SubmittedDateTime,
            CurrentUserExtId = curUserExtId
        });

        model.ListAlerts = alerts;

        model.ShowSubmittedDateTime = showSubmittedDateTime;
        model.ShowStatus = showStatus;
        model.ShowActions = showActions;
        model.ShowOwners = showOwners;

        return model;
    }
}

And this is the FindBy method I'm using from my repository:

public IQueryable<T> FindBy(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includeProperties)
    {
        IQueryable<T> query = this.Context.Set<T>();
        foreach (var include in includeProperties)
        {
            query.Include(include);
        }

        return query.Where(predicate);
    }