Asp.net mvc 3 如何跟踪MiniProfiler识别的重复Linq到SQL查询?

Asp.net mvc 3 如何跟踪MiniProfiler识别的重复Linq到SQL查询?,asp.net-mvc-3,linq-to-sql,profiling,mvc-mini-profiler,Asp.net Mvc 3,Linq To Sql,Profiling,Mvc Mini Profiler,我已经将MvcMiniProfiler连接到我的应用程序,它报告了重复的查询 我已在存储库中设置了断点 Public Function Read() As System.Linq.IQueryable(Of [Event]) Implements IEventRepository.Read Dim events = (From e In dc.Events Select e) Return events.AsQu

我已经将MvcMiniProfiler连接到我的应用程序,它报告了重复的查询

我已在存储库中设置了断点

    Public Function Read() As System.Linq.IQueryable(Of [Event]) Implements IEventRepository.Read
        Dim events = (From e In dc.Events
                      Select e)
        Return events.AsQueryable ''# BREAKPOINT HERE
    End Function
我找到了有问题的那一页

我的代码通过我的服务层两次点击
Read()
函数(这是出于设计,因为我不知道如何减少调用)

EventService
对IQueryable
Read

    Public Function GetHotEvents(ByVal skip As Integer) As List(Of Domain.Event) Implements IEventService.GetHotEvents

        Return _EventRepository.Read() _
            .Where(Function(e) e.EventDate >= Date.Today AndAlso
                               e.Region.Name = RegionName) _
            .OrderByDescending(Function(e) (((e.TotalVotes) * 2) + e.Comments.Count)) _
            .ThenBy(Function(e) e.EventDate) _
            .Skip(skip) _
            .Take(5) _
            .ToList()
    End Function
不幸的是,我不明白为什么MiniProfiler说有8个重复的查询(总共13个)

修订版
所以看起来好像Sam说我没有在我的查询中预加载我的关系

如何在Linq到SQL中适当地预加载关系?有人能给我一些建议吗

编辑
这是正在创建的ViewModel

Public Class EventsIndexViewModel
    Public Property Events As List(Of Domain.ViewModels.EventPreviewViewModel)
    Public Property PageNumber As Integer
    Public Property TotalEvents As Integer
    Public Property MapEventsList As List(Of Domain.Pocos.MapPin)
    Public Property JsonMapEventsList As String

    Sub New()
    End Sub

    Sub New(ByVal eventlist As List(Of Domain.Event), ByVal page As Integer, ByVal eventcount As Integer)

        _PageNumber = page
        __TotalEvents = eventcount

        Dim mel As New List(Of MapPin)
        _Events = New List(Of Domain.ViewModels.EventPreviewViewModel)
        For Each e In eventlist
            _Events.Add(New Domain.ViewModels.EventPreviewViewModel(e))
            mel.Add(New MapPin(e.Location.Latitude, e.Location.Longitude, e.Title, e.Location.Name, e.Location.Address))
        Next

        _MapEventsList = mel
        _JsonMapEventsList = (New JavaScriptSerializer()).Serialize(mel)

    End Sub
End Class
编辑-添加屏幕截图


您需要在相应的查询中
。包括(“位置”)
。包括(“注释”)
。我相信它在
.Where()
之前,但我对此并不乐观。

基本上有两个选项可以避免使用LINQ to SQL选择n+1:

1)使用数据加载选项

DataLoadOptions使您能够精确地为每个实体指定应加载的相关表。在您的情况下,对于实体事件,您可以为注释和位置指定LoadWith。无论何时加载事件,都会预加载注释和位置

DataLoadOptions是可以在DataContext本身上设置的属性

2)使用投影获取一个特定查询中所需的所有数据,而不是依赖于延迟加载相关实体

您已经在DataContext之上强加了一个存储库,因此这可能不是您想要采用的方法,但是:

不必选择事件列表,然后使用该实体的属性、注释和位置,您可以让查询返回特定ViewModel类中所需的内容。然后,LINQtoSQL将在一个SQL查询中获取所有内容

我认为这是最好的方法,如果您不需要抽象存储库接口后面的DATACONTRONT。即使您这样做,也可以考虑拥有库返回视图特定的结果,即

dc.Events
    .Where(something)
    .Skip(something)
    .Select(event => new EventViewModel 
        {
            Event = event
            Locations = event.Locations,
            Comments = event.Comments
        }
    );
使用EventViewModel

public class EventViewModel 
{
    Event Event;
    List<Location> Locations;
    List<Comment> Comments;
}
公共类事件视图模型
{
事件;
列出地点;
列出评论;
}

mini profiler为您显示了各种执行的堆栈跟踪,是否要包括查询时间线的屏幕截图?我已经添加了查询。。。我找不到堆栈跟踪这是典型的n+1类型,查询中的关系没有预加载,尤其是。注释和.LocationsAwesome。。。我对LINQ绝对没有“全面”的了解。在我的服务层中预加载关系的“正确”方法是什么?就我个人而言,我使用的是dapper:)更不用说伤脑筋了,但我听说这是可行的,或者你可以选择并分配你所有的EntityRef
public class EventViewModel 
{
    Event Event;
    List<Location> Locations;
    List<Comment> Comments;
}