C# 实体框架性能-如何使其快速工作?
我有一个对象,它有一个子对象列表,基本上是一个有多个部门的机构。可以根据部门上的布尔属性禁用或启用部门。如果有1个或多个部门处于禁用状态,我希望触发机构的属性为false。我的部分学院课程中有以下代码:C# 实体框架性能-如何使其快速工作?,c#,entity-framework,entity,C#,Entity Framework,Entity,我有一个对象,它有一个子对象列表,基本上是一个有多个部门的机构。可以根据部门上的布尔属性禁用或启用部门。如果有1个或多个部门处于禁用状态,我希望触发机构的属性为false。我的部分学院课程中有以下代码: public bool AllSet { get { return !(Departments.Where(i => i.Active == false && i.IsDeleted == false).Count() > 0);
public bool AllSet
{
get
{
return !(Departments.Where(i => i.Active == false && i.IsDeleted == false).Count() > 0);
}
}
这是可行的,但当我启用它时,我的页面的性能会显示机构列表慢到爬行,内存使用率会出现峰值,显然我在这里做了一些根本错误的事情,有人有其他方法可以做到这一点吗
工作解决方案
var institutions = from x in ent.Institutions let hasDepartments =
!x.Departments.Any(d => d.Active == false && d.IsDeleted == false) select new {
FullTitle = x.Title + " - " + x.Address.Line1 + ", " + x.Address.City + ", " + x.Address.State, Department = x, AllSet = hasDepartments, Guid = x.Guid
};
instList.DataSource = institutions;
您只需使用:
public bool AllSet
{
get
{
return !(Departments.Count(i => i.Active == false && i.IsDeleted == false) > 0);
}
}
这里有一些提高EF性能的技巧,请查看此。(对于那些使用EF的人来说,这是值得一读的)您应该通过使用以下查询找到边际性能优势。然而,主要问题是Linq表现不佳。根据定义,它是在运行时生成一个SQL查询,并为此生成大量元数据。您会发现.NET4.5在这方面的开销比.NET4.5低 如果第一次查询的成本似乎很大,那么也可能是由于视图创建过程造成的。您可以查看预编译视图。但最终如果你需要速度,就去别处看看。甚至可能是内联SQL
public bool AllSet
{
get
{
return !(Departments.Any(i => i.Active == false && i.IsDeleted == false));
}
}
编辑:我刚刚意识到你真正的问题。看起来,AllSet
是类机构上的一个方法,您在一个紧密循环中调用它。我认为它“工作”是因为延迟加载
这是非常糟糕的,因为每个循环都要进行一次数据库调用,这将是IO/延迟限制的,因此非常慢。此外,不再只是从数据库加载bool
,而是根据需要加载每个相关的部门
,然后在.net上本地运行.Count()
(因此内存占用较大)
如果每个机构都有活跃的部门,请尝试预先访问它们
var institutions = from x in context.Institutions
where {blah}
let hasDepartments = x.Departments.Any(d => d.Active == false
&& i.IsDeleted == false)
select new { Department = x, AllSet = hasDepartments};
foreach(var institution in institutions)
{
//DO STUFF
}
总的来说,真正的WTF依赖于EF延迟加载。这种方法使用的内存稍微少一些(可能没有什么不同),而且仍然非常慢。非常奇怪。或者你可以急切地加载部门,但这意味着加载所有部门,而不仅仅是一些bool…我喜欢将其全部工作到查询中的想法,我将在明天尝试此方法,并在后面发帖。我已将您的答案的变体添加到我的原始问题中,感谢您的帮助,从现在起,我将使用此方法填充更大的列表。