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 秒以上を意味しますが、最初のバージョンでは 1 秒未満で結果が得られます。)

2番目のアプローチを最適化する方法はありますか? または、最初のアプローチを機能させる方法はありますか?

4

2 に答える 2

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 に答える
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 に答える