J'ai suivi du tableau
db.DeviceLogs.GroupBy(g=>new {g.LogDate.Year,
g.LogDate.Month,
g.LogDate.Day,
g.LogDate.Hour,
g.LogDate.Minutes,
g.UserID})
.Select(s=>new {UserID=s.Key.UserID, s.???});
5 Réponses :
var result =
from log in db.DeviceLogs
let byId =
db.DeviceLogs.Where(item => item.UserId == log.UserId)
let first =
byId.First(item => item.LogDate == byId.Min(min => min.LogDate))
where
log.Equals(first) || (log.LogDate - first.LogDate).Minutes > 5
select log;
1 sec, pls. Semble que l'erreur est que vous comparez avec un minimumDate Element entre tous les enregistrements, pendant que vous devez comparer au minimum spécifique à l'utilisateur. Pls, vois ma réponse.
.where (item => item.userid == log.userid) code> contraintes Le jeu recherché sur l'utilisateur :)
C'est une version modifiée de votre réponse avec une sortie à Linqpad, bien que je ne nie pas votre réponse était une base. Et je t'ai donné un uppote
db.devicelogs.min (min => min.logdate) code> n'est pas contraint, c'est juste la date minimale
Vous faites à peine la même chose que moi et simplement mettre la chose de filtrage d'identifiant dans une variable supplémentaire ... votre réponse fait l'original la même chose que la mienne.
D'accord, puis changez votre réponse et je vais supprimer le mien.
@Janp. Merci de réponse .. Je vais essayer de revenir.
@Janp. Il fonctionne bien avec db.devicelogs code> mais il échoue si je travaille avec Liste
OK, que diriez-vous.
var firstDates = db.DeviceLogs.GroupBy(d => d.UserId).ToDictionary(
g => g.Key,
g => g.OrderBy(d => d.LogDate).First().LogDate);
db.DeviceLogs.GroupBy(g => new
{
v = Math.Floor(SqlMethods.DateDiffMinute(firstDates[d.UserId], g.LogDate) / 5),
u = g.UserID
}).Select(s => s.OrderBy(s => s.LogDate).First());
J'ai supprimé mon DV car ce n'est pas aussi faux comme je me suis trompé que je pensais à première vue, mais cela ne fera que observer le premier élément par utilisateur par une minute absolue plutôt qu'un premier article-per-utilisateur-perfublier-cinq -Minute-fenêtre.
@Rawling, modifié après des éclaircissements.
Cela donne une erreur dans l'énoncé de groupeBy: Déclarateur de membre anonyme non valide. Les membres de type anonyme doivent être déclarés avec une affectation de membre, un nom simple ou un accès membre. Code>
Je peux vous suggérer une solution SQL: voir fiddler http://sqlfiddle.com/#!6/fa74e/50 p> p>
Merci voo .. mais il est très difficile pour moi de le convertir en Linq: p
Je ne suis pas sûr de pouvoir le faire avec une seule instruction LINQ, car vous devez vous rappeler que la date d'heure du dernier enregistrement cédée.
Vous pouvez utiliser un bloc d'itérateur comme: où l'enregistrement serait une classe pour représenter un seul enregistrement, qui comprend une propriété DateTime de type DateTime code> (voir logDate code> est d'un type différent, vous devrez peut-être modifier le code un peu. P> p>
Ceci est ma solution
Je ne pense pas que vous puissiez le faire dans Linq-to-SQL. Vous pouvez le faire sous Linq-to-Objects en abusant code> Groupby Code> avec une comparaison personnalisée ou avec une méthode de type Linq personnalisée (bien que cela n'utilise plus Linq).
J'ai besoin d'un peu de clarification. Toutes les entrées après cinq minutes seront-elles incluses ou, l'échantillonnage continue-t-il? S'il se poursuit, les fenêtres de cinq minutes restent-elles basées sur la première entrée ou, chaque fenêtre commence-t-elle à partir du dernier accepté?
@JODRELL: Oui, seule la fenêtre est de 5 minutes, les entrées sont des mois et du long de l'année. Deuxièmement, cinq minutes de fenêtre restent basées sur la première entrée de l'ensemble de données de cet utilisateur spécifique.
@Marshal, restauration, peut répondre à un groupe dans des fenêtres de cinq minutes à basculer sur le premier événement.
Votre ligne
uniquement des enregistrements qui ont eu lieu après 5 minutes de l'enregistrement précédent sélectionné code> semble être en attente avecFenêtre de cinq minutes restent basés sur la première entrée code>.@Rawling: édité cette partie de clarification. Je savais qu'il serait difficile d'expliquer afin que j'ai également inclus la sortie
souhaitée code>Nous avons vraiment besoin de plus de données pour obtenir ce que vous voulez dire. Par exemple, si vous avez un enregistrement à 0:00, un enregistrement à 0:07, et un enregistrement à 0:11 (tous pour le même identifiant), avez-vous (a) définir vos fenêtres comme 0-5, 5- 10 et 10-15 et renvoyez ainsi tous les trois enregistrements car ils se trouvent tous dans des fenêtres séparées ou vous (b) renvoyez-vous 0:00, 0:07 (car 7-0> 5) mais pas 0:11 (parce que 11- 7 <5)?