1

我有看起来像这样的方法:

    private static IEnumerable<OrganizationViewModel> GetOrganizations()
    {
        var db = new GroveDbContext();

        var results = db.Organizations.Select(org => new OrganizationViewModel
        {
            Id = org.OrgID,
            Name = org.OrgName,
            SiteCount = org.Sites.Count(),
            DbSecureFileCount = 0,
            DbFileCount = 0
        });

        return results;
    }

这是非常迅速地返回结果。

但是,您会注意到 OrganizationViewModel 必须具有设置为“0”的属性。我通过部分类添加并用 [NotMapped] 修饰的组织模型中有一些属性:UnsecureFileCount 和 SecureFileCount。

如果我将那些 0 更改为有用的东西...

   DbSecureFileCount = org.SecureFileCount,
   DbFileCount = org.UnsecureFileCount

...我得到“仅支持初始化程序、实体成员和实体导航属性”异常。我觉得这有点令人困惑,因为我不觉得我在向数据库询问它们,我只是在设置视图模型的属性。

但是,由于 EF 没有听我的论点,我尝试了一种不同的方法:

    private static IEnumerable<OrganizationViewModel> GetOrganizations()
    {
        var db = new GroveDbContext();

        var results = new List<OrganizationViewModel>();
        foreach (var org in db.Organizations)
        {
            results.Add(new OrganizationViewModel
            {
                Id = org.OrgID,
                Name = org.OrgName,
                DbSecureFileCount = org.SecureFileCount,
                DbFileCount = org.UnsecureFileCount,
                SiteCount = org.Sites.Count()
            });
        }

        return results;
    }

从技术上讲,这毫无例外地给了我正确的结果,但这需要很长时间。(“永远”是指超过 60 秒,而第一个版本在一秒钟内提供结果。)

有没有办法优化第二种方法?或者有没有办法让第一种方法发挥作用?

4

2 回答 2

0

另一种选择是将值作为匿名类型加载回来,并通过这些循环加载您的视图模型(n+1 很可能是速度缓慢的原因)。

例如:

var results = db.Organizations.Select(org => new
        {
            Id = org.OrgID,
            Name = org.OrgName,
            DbSecureFileCount = org.SecureFileCount,
            DbFileCount = org.UnsecureFileCount,
            SiteCount = org.Sites.Count()
        }).ToList();

var viewmodels = results.Select( x=> new OrganizationViewModel
{
    Id = x.Id,
        Name = x.Name,
        DbSecureFileCount = x.DbSecureFileCount,
        DbFileCount = x.DbFileCount,
        SiteCount = x.SiteCount
});

抱歉格式化;我在手机上打字。

于 2012-11-15T23:30:48.043 回答
0

您基本上是在循环的每次迭代中延迟加载每个对象,从而导致 n+1 个查询。

您应该做的是将整个集合带入内存,然后从那里使用它。

示例代码:

var organizationList = db.Organizations.Load();
foreach (var org in organizationList.Local)
    {
       //Here you are free to do whatever you want
    }
于 2013-11-21T21:29:51.620 回答