2010-12-09 179 views
0

我有一个包装类用于MVC应用程序,该应用程序设计为循环访问集合中的项目,并检查当前用户是否具有访问该项目的权限它用于显示。大多数情况下,它就像一个魅力。然而,对于一个特定的对象类型,它像一只绝对的狗一样运行,我无法弄清楚为什么。实现IEnumerable的MoveNext内部MoveNext的糟糕表现<T>

接口类是这样写的:

private readonly IEnumerable<T> _ViewData; 

    public IEnumerator<T> GetEnumerator() 
    { 
     foreach (T item in _viewData) 
     { 
      if (item.UserCanEdit || item.UserCanView) 
       yield return item; 
     } 
    } 


    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

现在我的第一个问题是检查我怎么在这里上的理解。我可能是错的,但我的理解是,当我尝试运行一个针对类型对象集合的foreach循环时,它永远不需要使用System.Collections.IEnumerable.GetEnumerator() - 当然代码永远不会被击中?

问题在于,当我尝试在LogEntryViewDaya类中通过实体框架提供的日志文件条目上使用此包装器时,问题在于此。当代码击中GetEnumerator内部的foreach循环时,即使枚举中只有20个项目,它也会停留整整6-8秒!

下面是LogEntryView

public class LogEntryViewData:BaseViewData 
{ 
    private LogEntry _entry; 
    public LogEntryViewData(LogEntry entry, ICustomerSecurityContext securityContext) : base(securityContext) 
    { 
     _entry = entry; 
    } 

    public string Application { get { return _entry.Application; } } 
    public string CurrentUser { get { return _entry.CurrentUser; } } 
    public string CustomerName { get { return _entry.CustomerName; } } 
    public DateTime Date { get { return _entry.Date; } } 
    public string Exception { get { return _entry.Exception; } } 
    public string HostName { get { return _entry.HostName; } } 
    public long Id { get { return _entry.Id; } } 
    public string Level { get { return _entry.Level; } } 
    public string Message { get { return _entry.Message; } } 
    public int? ProcessId { get { return _entry.ProcessId; } } 
    public int? ServiceId { get { return _entry.ServiceId; } } 
    public string ServiceName { get { return _entry.ServiceName; } } 
    public int? TaskId { get { return _entry.TaskId; } } 
    public int? TaskName { get { return _entry.TaskName; } } 
    public string Thread { get { return _entry.Thread; } } 
} 

代码据我可以告诉有一个在实例化这些类没有明显的表现 - 把一个断点在构造和F5ing通过似乎光滑的东西。

那么为什么这些特定对象的集合如此缓慢地迭代?我不知道:感激的建议。

回答

2

您还没有向我们展示该课程是如何填充的。我的猜想是时间正在进行数据库查询 - 特别是取决于所获取的内容,可能只有一个查询来获取骨架实体,然后一个查询每个UserCanEditUserCanView。这似乎不太可能(我曾预计该条目将在初始查询中填充这些属性),但只是可能的。

基本上,看它如何与你的数据库进行交互。

我建议你尝试编写一个使用相同类的控制台应用程序,这样你就可以搞定它,比webapp更容易添加计时日志等。

编辑:除了评论等其他一切,是否有任何理由,你不这样做的一部分LINQ查询?例如:

var query = db.LogEntries.Where(x => x.UserCanEdit || x.UserCanView); 

我欣赏它可能不会是相当那样简单,因为UserCanEdit将取决于当前用户等等 - 但它可能应该做一个数据库查询,而不是客户端 - 侧。

+0

好的,在这里要表现出我的无知,但是我认为当它的构造函数被调用时,该类被填充了?这发生在它进入foreach循环之前,似乎以令人满意的速度发生。 – 2010-12-09 14:11:55