You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何用Sum方法累加TimeSpan属性实现课程按总时长排序

Asp.Net Core 按课程总时长排序解决方案

问题背景

我正在开发一个Asp.Net Core项目,定义了Course和Episode两个存在一对多关系的实体,每个Course包含多个Episode。

Episode实体代码

public  class Episode
{
    [Key]
    public int EpisodeId { get; set; }

    [Required]
    public int CourseId { get; set; }

    [Display(Name = "عنوان اپیزود")]
    [Required(ErrorMessage ="لطفا {0} را وارد کنید")]
    [MaxLength(ErrorMessage ="{0} نمیتواند بیش تر از {1}کاراکتر باشد")]
    public string EpisodeTitle { get; set; }

    public string EpisodeFileName { get; set; }

    [Display(Name = "مدت زمان اپیزود")]
    [Required(ErrorMessage = "لطفا {0} را وارد کنید")]
    public TimeSpan? EpisodeTimeLength { get; set; }

    [Display(Name = "رایگان")]
    [Required(ErrorMessage = "لطفا {0} را وارد کنید")]
    public bool IsFree { get; set; }

    public DateTime CreateDate { get; set; } = DateTime.Now;

    #region Navigation Properties
    [ForeignKey("CourseId")]
    public Course.Courses.Course Course { get; set; }
    #endregion
}

问题描述

我需要使用OrderBy()方法对课程排序,关联Episode的EpisodeTimeLength总时长越长的课程越靠前。比如课程1总时长12小时,课程2总时长15小时,排序后课程2排在首位。
我尝试了以下两种写法:

// 写法1
dbContext.Courses.OrderBy(c => new TimeSpan(c.Episodes.Sum(e=> e.EpisodeTimeLength.Ticks)));
// 写法2
dbContext.Courses.OrderBy(c => c.Episodes.Sum(e=> e.EpisodeTimeLength));

均报错:cannot implicity convert type 'System.TimeSpan' to 'long'


解决方案

错误原因

EF Core原生没有支持TimeSpan类型累加的Sum()重载方法,仅支持对long、int等数值类型求和,所以会报类型转换错误。同时你需要时长越长排序越靠前,应该用OrderByDescending(降序)而非OrderBy(升序)。

正确代码

你可以通过对TimeSpan的底层存储单位Ticks求和来实现需求,注意要处理TimeSpan?可空类型的null值:

var sortedCourses = dbContext.Courses
    // 按总时长降序排列,null的时长按0计算
    .OrderByDescending(c => c.Episodes.Sum(e => e.EpisodeTimeLength.HasValue ? e.EpisodeTimeLength.Value.Ticks : 0))
    .ToList();

如果你的业务逻辑通过[Required]校验已经保证EpisodeTimeLength不会出现null值,可以简化写法:

var sortedCourses = dbContext.Courses
    .OrderByDescending(c => c.Episodes.Sum(e => e.EpisodeTimeLength.Value.Ticks))
    .ToList();

实现原理

Ticks是TimeSpan的最小时间单位,1秒等于10000000个Ticks,对Ticks求和等价于对时间长度直接求和,EF Core可以正确将该写法翻译为SQL语句执行,不会出现类型转换错误。


内容的提问来源于stack exchange,提问作者Hossein

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 06:15:04