C# Linq查询在连接主详细信息时非常慢

C# Linq查询在连接主详细信息时非常慢,c#,linq,C#,Linq,我有一个MVC应用程序,我的主页显示信息的速度非常慢。我想这可能是我的linq问题。我检查了数据库并运行了一个类似的SQL,但速度不是很慢 我将数据从生产转移到我的开发笔记本电脑上进行测试,最初几分钟,页面在我的笔记本电脑上运行得非常快,但如果我继续使用该应用程序超过5分钟,即使在我的笔记本电脑上,页面也会变得非常慢!其他页面似乎运行良好 如何对此进行故障排除 基本上,我想做的是显示当天的作业列表和子记录的摘要 public class Assignment { [Key] [

我有一个MVC应用程序,我的主页显示信息的速度非常慢。我想这可能是我的linq问题。我检查了数据库并运行了一个类似的SQL,但速度不是很慢

我将数据从生产转移到我的开发笔记本电脑上进行测试,最初几分钟,页面在我的笔记本电脑上运行得非常快,但如果我继续使用该应用程序超过5分钟,即使在我的笔记本电脑上,页面也会变得非常慢!其他页面似乎运行良好

如何对此进行故障排除

基本上,我想做的是显示当天的作业列表和子记录的摘要

 public class Assignment
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int ID { get; set; }
    public string UserName { get; set; }
    public DateTime CreatedDate { get; set; }
    public string Status { get; set; }
    public bool IsArchived { get; set; }
    public int SortFlag { get; set; }
    public virtual ICollection<Adjustment> Adjustments { get; set; }
}

 public class Adjustment
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int ID { get; set; }
    public int AssignmentID { get; set; }
    public string Description { get; set; }
    public string UPC { get; set; }
    [Display(Name= "LicPlt")]
    public int? ExpectedLicensePlateID { get; set; }
    [Display(Name = "Product")]
    public string ExpectedProductID { get; set; }
    [Display(Name = "ExpCDate")]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime? ExpectedCodeDate { get; set; }
    [Display(Name = "ExpQTY")]
    public int ExpectedQty { get; set; }
    [Display(Name = "LotNumber")]
    public string ExpectedLotNumber { get; set; }
    [Display(Name = "ExpCool")]
    public string ExpectedCOOL { get; set; }

    [Display(Name = "LicPlt")]
    public int? ActualLicensePlateID { get; set; }
    public string ActualProductID { get; set; }
    [Display(Name = "CDate")]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime? ActualCodeDate { get; set; }


    [Display(Name = "QTY")]
    public int ActualQty { get; set; }

    [Display(Name = "LotNumber")]
    public string ActualLotNumber { get; set; }

    [StringLength(3, ErrorMessage = "Lenght should be 3")]
    [Display(Name = "Cool")]
    public string ActualCOOL { get; set; }
    [Display(Name = "Location")]
    public string LocationID { get; set; }
    public string UserName { get; set; }
    public DateTime UpdatedDateTime { get; set; }
    public DateTime ImportedDateTime { get; set; }
    public string Status { get; set; }

    [StringLength(2, ErrorMessage = "Lenght should be 2")]
    [Display(Name = "Reason")]
    public string ReasonCodeID { get; set; }
    public string Notes { get; set; }
    public string ReviewedBy { get; set; }
    public DateTime? ReviewedDateTime { get; set; }
    public string ReviewNotes { get; set; }
    public bool IsCodeDated { get; set; }


    public bool IsDescriptionConfirmed { get; set; }
    public bool IsCodeDateConfirmed { get; set; }
    public virtual Assignment Assignment { get; set; }

    public ReasonCode ReasonCode { get; set; }
    public string LocationCategory { get; set; }

}

问题出在linq最小和最大聚合中。不知道为什么,但可能是数据量

无论如何,我修改了查询,并且运行得非常快。从最小/最大更改为子查询

var assignmenTotal = new AssignmentUser
 {
     IsSupervisor = supervisor,
      AssignmentTotals = (from a in db.Assignments
     where (StartDate.HasValue) ? DbFunctions.TruncateTime(a.CreatedDate) == StartDate : a.IsArchived == false
     join b in db.Adjustments on a.ID equals b.AssignmentID
        group b by new {a.ID,a.UserName,a.Status,a.CreatedDate,a.IsArchived} into g
         select new AssignmentTotals
         {
             ID =  g.Key.ID,
             UserName = g.Key.UserName,
             Status = g.Key.Status,
             ImportedDate = DbFunctions.TruncateTime(g.Key.CreatedDate),
             StartingLocation = (db.Adjustments.Where(x=>x.AssignmentID == g.Key.ID).OrderBy(x=>x.LocationID).Select(x=>x.LocationID).FirstOrDefault()),
             EndingLocation = (db.Adjustments.Where(x => x.AssignmentID == g.Key.ID).OrderByDescending(x => x.LocationID).Select(x => x.LocationID).FirstOrDefault()),
             TotalLocations = g.Count(x => x.LocationID != null),
             TotalLicensePlates = g.Count(x => x.ExpectedLicensePlateID != null),
             TotalAdjCompleted = g.Count(x => x.Status == "C"),
             IsSameUser = (currUser == g.Key.UserName ? true : false),
             IsArchived = g.Key.IsArchived
         }).ToList()
};

你是说页面变得非常慢,但是你有没有具体分析过哪个部分慢?我想这是一个SQL问题。在SQL server实例上运行配置文件,并检查正在运行的实际SQL查询。这就是Linq2SQL的基本原因sucks@mason我按照本地SQL server上的建议运行了SQL探查器,只要单击submit按钮,我就会在探查器上看到一个“Audit Login”条目。在我的开发机器上,RPC completd实际查询的持续时间从300持续时间变为8000持续时间以上。这是在从Visual Studio运行时发生的。@Liam我想我发现了问题。问题在于最小和最大聚合部分。不知道为什么这么慢,或者我是否需要在这个字段上添加索引?它是在执行最小、最大SQL调用还是在内存中计算?内存中的MIN/MAX是一个On操作,因为它需要迭代整个结果集。如果您将其更改为SQL最小值,则它可能与索引一起是一个Olog n操作。也就是说,SQL的相对大O比SQL的C效率要高得多,因为SQL是基于集合论而不是迭代的。Tl;Dr您需要尝试将此操作推送到SQL上,并避免在内存中执行。我仍然认为使用SQL在SQL中执行此操作可能会更高效一个数量级。
var assignmenTotal = new AssignmentUser
 {
     IsSupervisor = supervisor,
      AssignmentTotals = (from a in db.Assignments
     where (StartDate.HasValue) ? DbFunctions.TruncateTime(a.CreatedDate) == StartDate : a.IsArchived == false
     join b in db.Adjustments on a.ID equals b.AssignmentID
        group b by new {a.ID,a.UserName,a.Status,a.CreatedDate,a.IsArchived} into g
         select new AssignmentTotals
         {
             ID =  g.Key.ID,
             UserName = g.Key.UserName,
             Status = g.Key.Status,
             ImportedDate = DbFunctions.TruncateTime(g.Key.CreatedDate),
             StartingLocation = (db.Adjustments.Where(x=>x.AssignmentID == g.Key.ID).OrderBy(x=>x.LocationID).Select(x=>x.LocationID).FirstOrDefault()),
             EndingLocation = (db.Adjustments.Where(x => x.AssignmentID == g.Key.ID).OrderByDescending(x => x.LocationID).Select(x => x.LocationID).FirstOrDefault()),
             TotalLocations = g.Count(x => x.LocationID != null),
             TotalLicensePlates = g.Count(x => x.ExpectedLicensePlateID != null),
             TotalAdjCompleted = g.Count(x => x.Status == "C"),
             IsSameUser = (currUser == g.Key.UserName ? true : false),
             IsArchived = g.Key.IsArchived
         }).ToList()
};