繁体   English   中英

ASP.NET和EF非常慢

[英]ASP.NET and EF are very very slow

通过使用EF,C#和ASP.NET 4 Web应用程序,我使用以下代码从数据库中检索数据并填充GridView:

using (AshModel am = this.conn.GetContext())
{
    IEnumerable<Article> articles = 
        (from a in am.Article.AsEnumerable()
         where (a.CultureName == calture || a.CultureName == 0)
             && a.IsApproved == status
             && a.IsPublished == status
         orderby a.AddedDate descending
         select a);

    IEnumerable<Profile> profiles = am.Profile.AsEnumerable()
        .Where(t => articles.Any(a => a.ProfileId == t.ProfileID));

    foreach (Article article in articles)
        article.UserProfile = profiles
            .Where(a => a.ProfileID == article.ProfileId)
            .FirstOrDefault();

    this.gvArticles.DataSource = articles.ToList();
    this.gvArticles.DataBind();
}

但它非常慢,响应大约需要2分钟,数据库中只有500条记录! 我的错误是什么? 我如何才能提高绩效? 谢谢。

你在某些部分正在做AsEnumerable()

执行此操作时,将从数据库中检索所有对象,然后对其进行过滤。

如果你删除那些AsEnumerable()它应该按预期工作。

您的第二和第三部分可以用简单的Include表达式替换:

 var articles = 
    (from a in am.Article
     .Include(article=>article.UserProfile) //!!
     where (a.CultureName == calture || a.CultureName == 0)
         && a.IsApproved == status
         && a.IsPublished == status
     orderby a.AddedDate descending
     select a).ToList();

//no more DB calls in foreach loop

this.gvArticles.DataSource = articles.ToList();
this.gvArticles.DataBind();

因为在您的代码中您首先选择文章,然后您找到至少在一篇文章中提到的配置文件(可以是整个数据集),然后您选择配置文件以匹配您的文章...

像这样的代码:

IEnumerable<Profile> profiles = am.Profile.AsEnumerable()
    .Where(t => articles.Any(a => a.ProfileId == t.ProfileID));

不会导致实际的集合/列表/任何实例化。 这仅仅是描述如何检索和过滤对象的配方,但Where子句中的lambda表达式不在上面的行中执行。 它只是一个表达式,用于定义如何在profiles集合中生成项目,但它不会生成它们。

一旦请求任何项目,就会发生该代码的实际执行,在您的示例中,它发生在.FirstOrDefault()调用上。 但是,它在一个循环中。 实际上,您将在循环的每个步骤中重新查找DB。

由于一次加载一堆DB记录要快得多,而不是单独加载它们,我建议将查询重写到Profile表中,以便在尽可能少的事务中加载它所需的全部内容。 对您而言,这意味着将代码段的第一行更改为:

IList<Article> articles = 
    (from a in am.Article
     where (a.CultureName == calture || a.CultureName == 0)
         && a.IsApproved == status
         && a.IsPublished == status
     orderby a.AddedDate descending
     select a).ToList();

IList<Profile> profiles = am.Profile.Where(t => articles.Any(a => a.ProfileId == t.ProfileID)).ToList();

总而言之,代码不一定在它发生的地方执行。 您可能希望在C#中进行Google 延迟执行

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM