Asp.net mvc 4 一瞥显示重复的EF查询

Asp.net mvc 4 一瞥显示重复的EF查询,asp.net-mvc-4,entity-framework-5,glimpse,Asp.net Mvc 4,Entity Framework 5,Glimpse,我的MVC4应用程序运行太慢,出现问题。我安装了Spile来分析应用程序。我想我已经发现了部分问题:我的许多EF查询似乎运行了两次!这是我的HomeController,它正在获取一些警报: [HttpGet] public virtual ActionResult Index() { var reportStart = DateTime.Today; var reportEnd = DateTime.Today.AddMonths(1);

我的MVC4应用程序运行太慢,出现问题。我安装了Spile来分析应用程序。我想我已经发现了部分问题:我的许多EF查询似乎运行了两次!这是我的HomeController,它正在获取一些警报:

[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);
    }
[HttpGet]
公共虚拟操作结果索引()
{
var reportStart=DateTime.Today;
var reportEnd=DateTime.Today.AddMonths(1);
变量查询=\u tameUow.Alerts
.FindBy(a=>a.ApprovalStatusId==(int)AlertApprovalStatusCodes.Approved&&
(a.ScheduledStartDateTime>=报告开始&&
a、 ScheduledStartDateTime a.SubmittedBy,a=>a.ApprovalManager,a=>a.ApprovalStatus);
var model=ListAlertsViewModelBuilder.Build(查询,null,false,false,false);
model.RequiredViewData=新的RequiredViewDataModel(“即将发布的警报”,“这些是下个月即将发布的活动警报。”,“主页”);
返回视图(模型);
}
但是,当我在“一瞥”中查看SQL选项卡时,它会显示两次查询!起初我认为这只是一个错误,同一个查询显示了两次,但它们的执行时间不同,因此我认为查询实际上运行了两次!此外,黄色的小感叹号会显示为警告。我认为这是在警告我它是错误的重复的查询

这是怎么回事?我在所有测试过的页面上都看到了这一点,我选择这一个作为示例,因为它是最简单的。我尝试在查询上设置断点,但只命中一次

以下是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;
    }
}
公共静态类ListAlertsViewModelBuilder
{
公共静态列表AlertsViewModel生成
(i)可查询的查询
,字符串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,
建筑物,
原因,
//注释,
冲击,
ScheduledEndDateTime=a.ScheduledEndDateTime,
ScheduledStartDateTime=a.ScheduledStartDateTime,
服务,
SubmittedBy=a.SubmittedBy,
SubmittedByExtId=a.SubmittedByExtId,
SubmittedDateTime=a.SubmittedDateTime,
CurrentUserExtId=curUserExtId
});
model.ListAlerts=警报;
model.ShowSubmittedDateTime=ShowSubmittedDateTime;
model.ShowStatus=ShowStatus;
model.ShowActions=ShowActions;
model.ShowOwners=ShowOwners;
收益模型;
}
}
这是我在存储库中使用的FindBy方法:

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);
    }
public IQueryable FindBy(表达式谓词,参数表达式[]includeProperties)
{
IQueryable query=this.Context.Set();
foreach(包含在includeProperties中的var)
{
查询.包含(Include);
}
返回query.Where(谓词);
}

您可以在查看SQL请求的同时单步查看代码吗?因为您从来没有明确地告诉您的查询执行它,所以应该在您调用模型的Build时执行。看起来您没有任何需要重新查询的导航属性(无论如何都不应该生成相同的SQL)。如果您单步执行,应该可以看到它们被触发的位置。我在Build()中设置了一个断点方法,它只命中一次构建本身只命中一次?您是否正在观察查询同时命中您的数据库?是的,构建只命中一次。我无法观察查询,因为我没有适当的工具来这样做…我所能看到的只是来自Glimpse的事实。我可以从一个粗略的角度验证这一点当发现同一查询被多次执行时,会显示警报图标。如果您在跟踪该查询时遇到问题,一个选项(这是一个让人头疼的问题,但会起作用)是下载Spile源代码,并在检测正在执行的命令的部分中放置断点。然后,您可以查看调用堆栈以查看e执行来自。此外,从我们的角度来看,如果我们可以做更多的工作来帮助您找到来源,而不必诉诸上述方法,那将是一件好事。