0

我有一个包含子对象列表的对象,基本上它是一个有多个部门的机构。可以根据部门的布尔属性禁用或启用部门。当有 1 个或多个部门被禁用时,我想将机构的属性触发为 false。我的部分机构课程中有以下代码:

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;
4

2 回答 2

1

您可以使用:

public bool AllSet
{
    get
    {
        return !(Departments.Count(i => i.Active == false && i.IsDeleted == false) > 0);
    }
}

有一些提示可以提高您的 EF 性能,请查看此链接。(对于使用EF的人来说,这值得一读)

于 2013-04-18T01:46:41.693 回答
1

您应该使用以下查询发现边际性能优势。然而,主要问题是 Linq 性能不佳。根据定义,它在运行时生成 SQL 查询,为此会生成大量元数据。您会发现 .net 4.5 在这方面的开销低于 .net 4。

如果第一次查询的成本似乎很大,也可能是由于视图创建过程。您可以查看预编译的视图。但最终,如果您需要速度,请寻找其他地方。甚至可能是内联 SQL。

public bool AllSet
{
    get
    {
        return !(Departments.Any(i => i.Active == false && i.IsDeleted == false));
    }
}

编辑:我刚刚意识到你真正的问题。它看起来像是AllSet机构类上的一个方法,你在一个紧密的循环中调用它。由于延迟加载,我认为它“工作”。

这是非常糟糕的,因为您将要进行数据库调用的每个循环,这将是 IO/延迟绑定,因此非常慢。此外,不仅仅是从数据库中加载一个,而是按需加载bool每个相关联的,然后在 .net 上本地运行(因此内存占用很大)。Department.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 延迟加载。

于 2013-04-18T02:05:49.907 回答