Sto cercando di creare una nuova app Web in VS2015 utilizzando il RC del nuovo asp.net e Entity Framework 7.
Una cosa che vorrei poter visualizzare è una colonna "totale di tempi".
Sto cercando di trovare un modo per recuperare la durata totale di tutti i dati video che sono stati caricati (sto usando NReco e FFProbe per ottenere le informazioni sui media dal file, che è il punto da cui ottengo la durata da a caricare nel DB)
Quando sto caricando dati video su un database, una delle proprietà nel mio modello Video è un oggetto TimeSpan.
Sono stato a strascicare la rete e SO per un po ', alcune delle soluzioni suggerite che ho provato non hanno funzionato (maggiori dettagli di seguito)
Per contesto, ecco il mio modello
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; }
}
e il mio controller
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
...
}
var minutesOfVideo = new TimeSpan(_context.Videos.Sum(v => v.VideoDuration.Ticks));
ma lancia un
Un'eccezione di tipo "System.InvalidCastException" si è verificata in EntityFramework.Core.dll ma non è stata gestita nel codice utente
Ulteriori informazioni: il cast specificato non è valido.
Ho anche provato a farlo
var minutesOfVideo = _context.Videos.Aggregate(TimeSpan.Zero, (sumSoFar, nextMyObject) => sumSoFar + nextMyObject.VideoDuration);
ma questo lancia un
Un'eccezione di tipo "System.NotImplementedException" si è verificata in EntityFramework.Core.dll ma non è stata gestita nel codice utente
Informazioni aggiuntive: Remotion.Linq.Clauses.ResultOperators.AggregateFromSeedResultOperator
E 'anche possibile o devo guardare a scrivere sia su Linq-> Sql o su qualche SQL nativo
Apprezzo qualsiasi risposta se questo è fattibile
MODIFICARE
Basato sul suggerimento di @ Ricky (grazie tra l'altro)
Se ci provo
var minutesOfVideo = _context.Videos.Select(v => v.VideoDuration).ToArray();
Ricevo Un'eccezione di tipo "System.InvalidCastException" si è verificata in EntityFramework.Core.dll ma non è stata gestita nel codice utente , provando
var minutesOfVideo = _context.Videos.Select(v => v.VideoDuration).ToArray().Sum();
Ottengo errori del compilatore
'TimeSpan []' non contiene una definizione per 'Sum' e il metodo di estensione migliore overload 'AsyncEnumerable.Sum (IAsyncEnumerable)' richiede un destinatario di tipo 'IAsyncEnumerable'
Sto iniziando a chiedermi se valga la pena rimuovere l'intervallo di tempo dal mio modello video e sostituirlo con due int per ore e minuti ...
Così, ho finito per prendere l'approccio di modificare il mio modello Video con due nuove proprietà
public int VideoMinutes { get; set; }
public int VideoSeconds { get; set; }
quindi da NReco.GetMediaInfo ottengo il mio oggetto TimeSpan, da cui compongo i miei due nuovi campi come proprietà dall'oggetto TimeStamp costruito.
Questo mi consente quindi di fare quanto segue nel mio 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);
Potrebbe non essere la soluzione più pulita ma questo mi sta fornendo ciò di cui ho bisogno al momento.
Solitamente EF 7 proverà a convertire le espressioni LINQ in istruzioni SQL. Sebbene abbia funzionalità limitate che combinano la query del database e le proprietà della classe che accedono.
Suggerisco di interrogare tutti i VideoDuration
dal database, ToArray
quindi invocare Sum VideoDuration
:
_context.Videos.Select(v => v.VideoDuration)
.ToArray()
.Select(vd => vd.TotalMinutes)
.Sum() // the return value is of type double