ASP.NET MVC, Entity Framework и производительность - PullRequest
0 голосов
/ 05 октября 2011

У меня проблемы с производительностью и я не понимаю поведение EF.Я использую приложение ASP.NET MVC и имею следующий код в модели:

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;
}

Я вызываю его из контроллера:

        portalList = _repository.PortalListWithCategories();

, как я понимаю, EF должен выполнить пакетный запрос и возвратКоллекция порталов с вложенными коллекциями «Категории» и «Идеи».

Но на мой взгляд, у меня есть следующее:

                @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++;
                    }
                }

, как я понимаю, у меня не должно быть новых запросов к БД, ноУ меня и очень много.Почему?

[ДОБАВЛЕНО]

Я обнаружил, что это строка (из e в категории. Идеи, где e.Portals.Any (t => t.PortalID ==portal.PortalID) выберите e) .Count () генерирует много запросов к БД, например:

exec sp_executesql N'SELECT [Extent2]. [PortalID] AS [PortalID], [Extent2]. [PortalName] AS [PortalName], [Extent2]. [DefaultPortal] AS [DefaultPortal] FROM [dbo]. [PortalIdeas] AS [Extent1] INNER JOIN [dbo]. [Порталы] AS [Extent2] ON [Extent1]. [PortalID] = [Extent2]. [PortalID] WHERE [Extent1]. [IdeaID] = @ EntityKeyValue1 ', N' @ EntityKeyValue1 int ', @ EntityKeyValue1 = 5618

почему это происходит для Count ()?

секундавопрос как правильно это сделать?

1 Ответ

1 голос
/ 05 октября 2011

Поскольку e.Portals не загружен и в вашем цикле foreach, EF должен совершить круговую поездку в базу данных, чтобы получить Portals для Idea.
Вы также должны включить Ideas в свой запрос.

Я не проверял это, но я думаю, что вы должны добавить .Include("Ideas.Portals") (или, если вы используете EF 4.1, добавьте using System.Data.Entity и используйте .Include(c => c.Ideas.Portals)).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...