ASP.NET和EF非常非常慢
本文关键字:非常 EF NET ASP | 更新日期: 2023-09-27 18:00:12
通过使用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#中搜索延迟执行。