Visual Studio 2019; ASP.Net Core 2.1
J'ai un système de base de données qui a un tableau des événements qui se produisent sur différentes machines.
8/2/2004 8:05:27 PM / 5/2/2019 12:00:00 AM
Je veux récupérer l'événement le plus ancien et le plus récent dates pour une machine particulière. Dans SSMS, je peux obtenir les informations que je veux avec:
public class VisibleRange {
public DateTime start { get; set; }
public DateTime end { get; set; }
}
...
var ctx = userTrackingContext.EventLog;
usertrackingRange = (
from eventLog in userTrackingContext.EventLog
where eventLog.Machine.ToUpper().Split(
'.',
StringSplitOptions.RemoveEmptyEntries
)[0].Trim().Equals(myMachine)
select eventLog.Date
).Select(range => new VisibleRange {
start = ctx.Min(a => a.Date),
end = ctx.Max(a => a.Date)
}).First();
Dans un exemple d'exécution, j'obtiens des valeurs min / max de:
2015-08-17 10:31:47.000 / 2019-05-02 12:54:20.000
Remarque: machineName peut être une chaîne "simple" comme "mypc" ou un FQDN ("mypc.company.com"). J'ai divisé le premier segment "pointillé" du FQDN possible et je le compare à la variable myMachine qui a déjà eu des parties pointillées supprimées.
En C #, je suis conscient qu'il y a sont des méthodes agrégées mais j'ai du mal à suivre les documents et les exemples que j'ai trouvés et à les traduire dans la pratique réelle. J'ai jusqu'à présent:
SELECT
MIN([eventDate]),
MAX([eventDate])
FROM eventLog
WHERE UPPER(machineName) LIKE 'MY-MACHINENAME%';
Cela fonctionne mais ne me donne pas de résultats utiles pour la valeur Min. Ce délai est d'environ 11 ans.
// pseudo code
eventLog (
id int primary key not null,
eventType varchar(16) not null,
machineName varchar(64) not null,
loggedInUser varchar(16) not null,
eventDate datetime not null,
)
Comment puis-je convertir la requête SSMS en requête LINQ?
3 Réponses :
Vous pouvez essayer de suivre la requête LINQ
usertrackingRange = (
from eventLog in userTrackingContext.EventLog
where eventLog.Machine.ToUpper().Split(
'.',
StringSplitOptions.RemoveEmptyEntries
)[0].Trim().Equals(myMachine)
select eventLog.Date
).Select(range => new VisibleRange {
start = ctx.OrderByAscending(a => a.Date).First(),
end = ctx.OrderByDescending(a => a.Date).First()
}).First();
Dans les lignes ctx.OrderBy ... , on me dit que je ne peux pas convertir du type ctx en DateHeure . Je ne vois pas de moyen de contraindre cela.
J'ai fait un test de fumée rapide et vos sélections fonctionnent pour moi. Pourquoi n'appelez-vous pas range.Min et range.Max pour obtenir les résultats de votre ensemble de données filtré?
var now = DateTime.Now;
var nums = new List<Num>
{
new Num { Min = now, Max = now.AddDays(1) },
new Num { Min = now.AddDays(10), Max = now.AddDays(50) },
new Num { Min = now.AddDays(51), Max = now.AddDays(100) },
};
var minMaxNum = nums.Select(num => new Num
{
Min = nums.Min(_ => _.Min),
Max = nums.Max(_ => _.Max),
}).First();
Vous pouvez essayer comme: -
var range = new VisibleRange() { };
var matched = userTrackingContext.EventLog.Where(a => a.MachineName.StartsWith(myMachine));
if(matched != null)
{
range.start = matched.Min(a => a.EventDate);
range.end = matched.Max(a => a.EventDate);
}