C# }; } 可能重复的可能重复的可能重复的感谢您的时间,但这不是我的意思。让我更详细一点:我试图找到一种方法,在其他地方重复使用我的部分查询。您的示例是我最初发布的示例的一个更干净(而且我相信性能更高)的版本,但具有我试图绕过的相同限制:即我无法将EndTi

C# }; } 可能重复的可能重复的可能重复的感谢您的时间,但这不是我的意思。让我更详细一点:我试图找到一种方法,在其他地方重复使用我的部分查询。您的示例是我最初发布的示例的一个更干净(而且我相信性能更高)的版本,但具有我试图绕过的相同限制:即我无法将EndTi,c#,.net,linq,C#,.net,Linq,}; } 可能重复的可能重复的可能重复的感谢您的时间,但这不是我的意思。让我更详细一点:我试图找到一种方法,在其他地方重复使用我的部分查询。您的示例是我最初发布的示例的一个更干净(而且我相信性能更高)的版本,但具有我试图绕过的相同限制:即我无法将EndTime/StartTime/HasWatchedAllvideos的概念分解为可重用的代码块。@Merritt:计算索引如何?插入速度会降低,以计算所有视频,保存最小值和最大值,但我想,阅读(这种情况更常见)速度会显著提高。感谢您抽出时间,但这不

}; }
可能重复的可能重复的可能重复的感谢您的时间,但这不是我的意思。让我更详细一点:我试图找到一种方法,在其他地方重复使用我的部分查询。您的示例是我最初发布的示例的一个更干净(而且我相信性能更高)的版本,但具有我试图绕过的相同限制:即我无法将EndTime/StartTime/HasWatchedAllvideos的概念分解为可重用的代码块。@Merritt:计算索引如何?插入速度会降低,以计算所有视频,保存最小值和最大值,但我想,阅读(这种情况更常见)速度会显著提高。感谢您抽出时间,但这不是我的意思。让我更详细一点:我正在试图找出一种方法,在其他地方重复使用部分查询。您的示例是我最初发布的示例的一个更干净(而且我相信性能更高)的版本,但具有我试图绕过的相同限制:即我无法将EndTime/StartTime/HasWatchedAllvideos的概念分解为可重用的代码块。@Merritt:计算索引如何?插入速度会降低,以计算所有视频,保存最小值和最大值,但我猜,阅读(这种情况更常见)速度会显著提高。
return from e in _context.Employees
       let HasWatchedAllVideos = 
       (
           from ev in _context.EmployeeVideos
           where ev.EmployeeId == e.Id && ev.EndTime.HasValue
           select ev.Id
       ).Count() == _context.Videos.Count()
       let EndTime = HasWatchedAllVideos ?
       (
           from ev in _context.EmployeeVideos
           where ev.EmployeeId == e.Id
           select ev.EndTime
       ).Max() : null
       let StartTime =
       (
           from ev in _context.EmployeeVideos
           where ev.EmployeeId == e.Id
           select ev.StartTime
       ).Min()
       select new EmployeeListItem
       {
           Id = e.Id,
           FirstName = e.FirstName,
           LastName = e.LastName,
           Company = e.Company,
           HasWatchedAllVideos = HasWatchedAllVideos,
           StartTime = StartTime,
           EndTime = EndTime
       };
let HasWatchedAllVideos = 
(
    from ev in _context.EmployeeVideos
    where ev.EmployeeId == e.Id && ev.EndTime.HasValue
    select ev.Id
).Count() == _context.Videos.Count()
private bool HasWatchedAllVideos(int employeeId)
{
    return (from ev in _context.EmployeeVideos
            where ev.EmployeeId == employeeId && ev.EndTime.HasValue
            select ev.Id
            ).Count() == _context.Videos.Count();
}
public class AdaTrainingService : ADATraining.Web.Models.IAdaTrainingService, IDisposable
{
    private ADATrainingEntities _context = new ADATrainingEntities();

    public IQueryable<EmployeeListItem> GetEmployeeListing()
    {
        return from e in _context.Employees
               join evsws in EmployeeVideoAggregatesView() on e.Id equals evsws.EmployeeId
               select new EmployeeListItem
               {
                   Id = e.Id,
                   FirstName = e.FirstName,
                   LastName = e.LastName,
                   Company = e.Company,
                   HasWatchedAllVideos = evsws.HasWatchedAllVideos,
                   StartTime = evsws.StartTime,
                   EndTime = evsws.EndTime
               };
    }

    private class EmployeeVideoSeriesWatchingStats
    {
        public int EmployeeId { get; set; }
        public DateTime? StartTime { get; set; }
        public DateTime? EndTime { get; set; }
        public bool HasWatchedAllVideos { get; set; }
    }

    private IQueryable<EmployeeVideoSeriesWatchingStats> EmployeeVideoAggregatesView()
    {
        return from ev in _context.EmployeeVideos
               group ev by ev.EmployeeId into myGroup
               select new EmployeeVideoSeriesWatchingStats
               {
                   EmployeeId = myGroup.Key,
                   StartTime = myGroup.Min( x => x.StartTime),
                   EndTime = myGroup.Max( x => x.EndTime),
                   HasWatchedAllVideos = myGroup.Count() ==  _context.Videos.Count()
               };
    }   

    public void Dispose()
    {
        _context.Dispose();
    }
}
public IQueryable<EmployeeDetails> GetEmployeeListing()
{
    return from e in _context.Employees
           join evsws in EmployeeVideoAggregatesView() on e.Id equals evsws.EmployeeId into myJoin
           from mj in myJoin.DefaultIfEmpty()
           select new EmployeeDetails
           {
               Id = e.Id,
               FirstName = e.FirstName,
               LastName = e.LastName,
               Company = e.Company,
               BadgeNumber = e.BadgeNumber,
               Title = e.Title,
               HasWatchedAllVideos = (mj.HasWatchedAllVideos == null) ? false : mj.HasWatchedAllVideos,
               StartTime = mj.StartTime,
               EndTime = mj.EndTime
           };
}
// don't count every time
var totalCount = _context.Videos.Count();

from e in _context.Employees
let HasWatchedAllVideos =
    totalCount ==
    _context.EmployeeVideos.Count(ev => ev.EmployeeId == e.Id && ev.EndTime.HasValue)

// count just once per employee
let employeeVideos =  _context.EmployeeVideos.Count(ev => ev.EmployeeId == e.Id)

let EndTime = HasWatchedAllVideos ? employeeVideos.Max() : null
let StartTime =  HasWatchedAllVideos ? employeeVideos.Min() : null

select new EmployeeListItem
{
    Id = e.Id,
    FirstName = e.FirstName,
    LastName = e.LastName,
    Company = e.Company,
    HasWatchedAllVideos = HasWatchedAllVideos,
    StartTime = StartTime,
    EndTime = EndTime
};