2011-10-05 3 views
0

J'ai un problème avec les performances et ne comprends pas le comportement de EF. J'utiliser l'application ASP.NET MVC et ont le code suivant dans le modèle:ASP.NET MVC, Entity Framework et la performance

public List<Portal> PortalListWithCategories() 
{ 
    List<Portal> q = new List<Portal>(); 
     q = (from i in _dataContext.Portals.Include("Categories").Include("Ideas") where i.Categories.Count > 0 orderby i.DefaultPortal descending select i).ToList(); 
    return q; 
} 

Je l'appelle du contrôleur:

 portalList = _repository.PortalListWithCategories(); 

que je comprends, EF doit exécuter la demande de traitement par lots et retour collection de portails avec collections imbriquées "Catégories" et "Idées".

Mais je vue suivant:

   @foreach (var category in portal.Categories.Where(n => n.Ideas.Count > 0 && n.Portals.Any(g => g.PortalID == portal.PortalID))) 
       { 
        if ((from e in category.Ideas where e.Portals.Any(t => t.PortalID == portal.PortalID) select e).Count() > 0) 
        { 
         string categoryLink = Url.RouteUrl("Full", new { PortalID = portal.PortalID, CategoryID = category.CategoryID, action = "Ideas" }); 
         List<NEOGOV_Ideas.Models.Ideas> ideas = category.Ideas.Where(o => o.Portals.Any(p => p.PortalID == portal.PortalID) && o.Categories.Any(h => h.CategoryID == category.CategoryID)).OrderByDescending(k => k.CreatedDateTime).ToList(); 
        <div class="grid_4"> 
         <h4> 
          <a href="@categoryLink">@category.CategoryName<span class="count_link">&nbsp;(@ideas.Count())</span> 
           <span class="follow_link">&raquo;</span></a></h4> 
         <ul> 
          @foreach (var idea in ideas.Take(3)) 
          { 
           string ideaLink = Url.RouteUrl("IdeaShort", new { id = idea.IdeaID }); 
           if (!idea.IdeaTypeReference.IsLoaded) { idea.IdeaTypeReference.Load(); } 
           string cssclass = " class=\"" + idea.IdeaType.TypeName.ToLower() + "\""; 
           <li><a href="@ideaLink" @cssclass>@idea.Title</a></li> 
          } 
         </ul> 
        </div> 
          if (i == 2) 
          { 
        <div class="clear"> 
        </div> 
          } 
          i++; 
        } 
       } 

que je comprends, je ne devrais pas avoir de nouvelles demandes de DB, mais je dois et très nombreux. Pourquoi?

[AJOUTÉE]

Je trouve que cette chaîne (de e dans category.Ideas où e.Portals.Any (t => t.PortalID == portal.PortalID) select e) .Count() génère de nombreuses demandes à DB comme:.

exec sp_executesql N'SELECT [Extent2] [PortalID] AS [PortalID], [Extent2] [PortalName] AS [PortalName], [Extent2].. [DefaultPortal] AS [DefaultPortal] FROM [dbo]. [PortalIdeas] AS [étendue1] INNER JOIN [dbo]. [Portals] AS [Extent2] ON [Extent1]. [PortalID] = [Extent2]. [PortalID] WHERE [Extent1]. [IdeaID] = @ EntityKeyValue1 ', N' @ EntityKeyValue1 int ' , @ EntityKeyValue1 = 5618

pourquoi cela arrive pour Count()?

deuxième question comment faire correctement?

Répondre

1

Parce que e.Portals n'est pas chargé et dans votre boucle foreach, EF doit avoir un aller-retour à la base de données pour aller chercher Portals pour Idea. Vous devez également inclure Ideas dans votre requête.

Je n'ai pas testé cela mais je pense que vous devriez ajouter .Include("Ideas.Portals") (ou si vous utilisez EF 4.1, ajoutez using System.Data.Entity et utilisez .Include(c => c.Ideas.Portals)).

Questions connexes