整體框架7 / LINQ - 獲取時間跨度對象的總和

c# entity-framework entity-framework-core sum timespan

我正在嘗試使用新的asp.net和Entity Framework 7的RC在VS2015中構建一個新的Web應用程序。

我希望能夠顯示的一件事是“總時間跨度”列。

我正試圖找到一種能夠檢索已上傳的所有視頻數據的總持續時間的方法(我正在使用NReco和FFProbe從文件中獲取媒體信息,這是我從中獲取持續時間的地方上傳到DB)

當我將視頻數據上傳到數據庫時,我的視頻模型中的一個屬性是TimeSpan對象。

我已經在網上拖網了一段時間,我試過的一些建議的解決方案沒有用(下面有更多細節)

對於上下文,這是我的模型

public class Video
{
    public int Id { get; set; }
    public DateTime DateOfVideo { get; set; }
    public string Road { get; set; }
    public string RegistrationNumber { get; set; }
    public List<Keyword> Keywords { get; set; }
    public TimeSpan VideoDuration { get; set; }
    public string User { get; set; }
    public DateTime UploadDate { get; set; }
}

和我的控制器

public class HomeController : Controller
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly IHostingEnvironment _environment;
    private readonly CcContext _context;

    public HomeController(UserManager<ApplicationUser> userManager, IHostingEnvironment environment, CcContext context)
    {
        _userManager = userManager;
        _environment = environment;
        _context = context;
    }
    ... 
    Various controller actions and methods removed for brevetiy 
    ...
}

到目前為止我嘗試過的事情

基於這個SO答案

 var minutesOfVideo = new TimeSpan(_context.Videos.Sum(v => v.VideoDuration.Ticks)); 

但扔了一個

EntityFramework.Core.dll中出現“System.InvalidCastException”類型的異常,但未在用戶代碼中處理

附加信息:指定的演員表無效。

我也嘗試過這樣做

var minutesOfVideo  = _context.Videos.Aggregate(TimeSpan.Zero, (sumSoFar, nextMyObject) => sumSoFar + nextMyObject.VideoDuration);

但這引發了一場

EntityFramework.Core.dll中出現“System.NotImplementedException”類型的異常,但未在用戶代碼中處理

其他信息:Remotion.Linq.Clauses.ResultOperators.AggregateFromSeedResultOperator

這是否可能,或者我是否需要編寫一些Linq-> Sql或一些本機SQL

如果這是可行的,我感謝任何答案

編輯

基於@Ricky的建議(感謝順便說一下)

如果我試試

var minutesOfVideo = _context.Videos.Select(v => v.VideoDuration).ToArray();

我得到EntityFramework.Core.dll中出現類型'System.InvalidCastException'的異常,但未在用戶代碼中處理 ,嘗試

var minutesOfVideo = _context.Videos.Select(v => v.VideoDuration).ToArray().Sum();

我收到編譯器錯誤

'TimeSpan []'不包含'Sum'的定義,最好的擴展方法重載'AsyncEnumerable.Sum(IAsyncEnumerable)'需要'IAsyncEnumerable'類型的接收器

我開始懷疑它是否值得我從我的視頻模型中移除timespan屬性並將其替換為兩個int的小時和分鐘......

一般承認的答案

所以,我最終採用了兩種新屬性來編輯我的視頻模型的方法

public int VideoMinutes { get; set; }
public int VideoSeconds { get; set; }

然後從NReco.GetMediaInfo得到我的TimeSpan對象,從我將我的兩個新字段填充為構造的TimeStamp對象的屬性。

然後,我允許我在HomeController中執行以下操作

        var totalMinsOfVideo = _context.Videos.Select(v => v.VideoMinutes).Sum();
        var totalSecsOfVideo = _context.Videos.Select(v => v.VideoSeconds).Sum();
        var total = new TimeSpan(0, totalMinsOfVideo, totalSecsOfVideo);

它可能不是最乾淨的解決方案,但這為我提供了我目前所需要的。


熱門答案

通常,EF 7會嘗試將LINQ表達式轉換為SQL語句。雖然它具有組合數據庫查詢和類屬性訪問的有限功能。

我建議您可以從數據庫查詢所有VideoDurationToArray然後在數組上調用Sum:

_context.Videos.Select(v => v.VideoDuration)
    .ToArray()
    .Select(vd => vd.TotalMinutes)
    .Sum() // the return value is of type double


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因