渴望在n + 1情况下加载VS延迟加载

时间:2013-11-12 19:02:20

标签: performance entity-framework lazy-loading database-performance eager-loading

如何通过这样的复杂数据查询来获得良好的性能:

在我的数据访问层中:

public IEnumerable<Serie> Search(SearchCriteria searchCriteria)
{
    //Operation to have my predicate...
    return ListAll().Where(predicate);
}

在我的SerieFicheViewModel适配器中,为了使我的实体适应ViewModel:

public static List<SerieFicheViewModel> ToViewModel(int utilisateurProfilId, IEnumerable<Serie> series, int utilisateurId, List<string> roles)
{
    IEnumerable<SerieFicheViewModel> seriesFiches =
                from s in series
                select new SerieFicheViewModel
                {
                    serie = SerieAdapter.ToViewModel(s, utilisateurId, SerieAdapter.TypeReponseEnum.Small),
                    serieUtilisateur = SerieUtilisateurAdapter.ToViewModel(s, utilisateurId, roles)
                };

    return seriesFiches.ToList();
}

我的SerieAdapter:

public static SerieViewModel ToViewModel(Serie serie, int utilisateurId, TypeReponseEnum typeReponse)
{
    SaisonBusiness _saisonBusiness = (SaisonBusiness)UnityHelper.BusinessResolve<Saison>();
    EpisodeBusiness _episodeBusiness = (EpisodeBusiness)UnityHelper.BusinessResolve<Episode>();

    int nombreSaisonsValides = _saisonBusiness.GetNombreSaisonsValides(serie.serie_id);

    SerieViewModel SerieViewModel = new SerieViewModel
    {
        id = serie.serie_id,
        dateAjout = serie.serie_dateajout.ToString("dd/MM/yyyy HH:mm"),
        nomVf = serie.Prestation.prestation_nom,
        nomOriginal = serie.Prestation.prestation_nom2,
        nom = serie.Prestation.prestation_nom,
        imageThumbUrl = !string.IsNullOrEmpty(serie.Prestation.prestation_image_thumb) ? ConfigurationManager.AppSettings["AddictLive_BaseUrl"] + serie.Prestation.prestation_image_thumb.Replace("~", "").Substring(1) : string.Empty,
        imageUrl = !string.IsNullOrEmpty(serie.Prestation.prestation_image) ? ConfigurationManager.AppSettings["AddictLive_BaseUrl"] + serie.Prestation.prestation_image.Replace("~", "").Substring(1) : string.Empty,
        noteMoyenne = serie.Prestation.PrestationNotes.Count() > 0 ? serie.Prestation.PrestationNotes.Select(pn => pn.note).Average() : 0,
        synopsis = serie.Prestation.prestation_description,
        format = serie.serie_format,
        nombreDeNotes = serie.Prestation.PrestationNotes.Count(),
        remerciement = serie.UserAuth != null ? serie.UserAuth.DisplayName : string.Empty,
        statusProduction = serie.StatusProduction != null ? serie.StatusProduction.statusproduction_nom : string.Empty,
        duree = RenseignerDuree(serie),
        nombreSaisons = nombreSaisonsValides,
        nombreEpisodes = _episodeBusiness.GetNombreEpisodesValides(serie.serie_id),
        videoPrincipale = serie.serie_videoprincipale
    };

    SerieViewModel.ficheUrl = UrlTool.GetSerieFicheUrl(serie.serie_id, serie.Prestation.prestation_nom);

    PrestationNoteBusiness _prestationNoteBusiness = (PrestationNoteBusiness)UnityHelper.BusinessResolve<PrestationNote>();
    SerieViewModel.noteMoyenneEpisodes = _prestationNoteBusiness.GetMoyenneDeTousLesEpisodes(serie.serie_id);

    //Dispo tout le temps pour afficher un lien vers la premiere saison une fois qu'on a mis une série comme vue
    Saison saison = nombreSaisonsValides > 0 ? _saisonBusiness.GetPremiereSaisonValide(serie.serie_id) : null;
    if(saison != null)
        SerieViewModel.saisonUrl = UrlTool.GetSaisonUrl(saison.saison_id, saison.saison_numero.ToString(), serie.Prestation.prestation_nom);

    return SerieViewModel;
}

我没有把所有代码都设置为不污染请求,但你可以看到我的适配器很复杂,我不知道如何定制它们。

在上面的示例中,我使用延迟加载,并且在我的数据库中执行了超过215个查询

如果我尝试使用Entity Framework Profiler软件中推荐的预先加载:

public IEnumerable<Serie> Search(SearchCriteria searchCriteria)
{
    //Operation to have my predicate...
    return ListAll().Include(s => s.Prestation.PrestationNotes)
    .Include(s => s.UtilisateurSerieEtats)
    .Include(s => s.UtilisateurSerieSuivies)
    .Include(s => s.Saisons.Select(sai => sai.Episodes))
    .Where(predicate);
}

实体框架Profiler说这次加入太多了...... 显然我的请求太大了,恢复了太多的数据但是如何削减我的代码并提高性能?我几乎所有的适配器都有这种情况,我需要你的帮助。

提前感谢所有花时间阅读并帮助我的人

1 个答案:

答案 0 :(得分:0)

提高性能的一种方法是创建一个视图(或多个视图)。然后,您的EF查询可以查询更简单的结构,并在一次调用时将所有数据拉回来。

根据您可用的SQL Server版本,您可以使用索引视图,这会对性能产生巨大影响。