如何解决查询中的NotMapped属性?

时间:2012-11-15 23:04:04

标签: c# entity-framework entity-framework-5

我的方法看起来像这样:

    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秒,而第一个版本在一秒钟内提供结果。)

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

2 个答案:

答案 0 :(得分:0)

另一种选择是将值作为匿名类型加载回来,然后循环加载你的viewmodel(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
});

抱歉格式化;我正在打电话。

答案 1 :(得分:0)

在循环的每次迭代中,你基本上都是懒惰加载每个对象,导致n + 1个查询。

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

示例代码:

var organizationList = db.Organizations.Load();
foreach (var org in organizationList.Local)
    {
       //Here you are free to do whatever you want
    }