J'ai une exigence apparemment simple, mais je ne peux pas comprendre comment l'écrire comme une requête qui a seulement un aller-retour au serveur.Linq requête agrégée par mois actif
Fondamentalement, j'ai une simple table
CREATE TABLE Item
(
id int not null identity(1,1),
create datetime not null,
close datetime --null means not closed yet
);
et ce que je veux faire est sur une plage de temps (disons 1/1/2010 à 6/1/2010), pour chaque mois j'ai besoin du nombre d'articles actifs pendant ce mois. un élément est actif s'il a été créé pendant ou avant ce mois et qu'il n'est pas fermé (c'est-à-dire fermé est nul) ou a été fermé après ce mois. Donc, je traduis que dans une expression LINQ en utilisant une méthode d'assistance:
//just returns the first day of every month inbetween min and max (inclusive)
private IEnumerable<DateTime> EnumerateMonths(DateTime Min, DateTime Max)
{
var curr = new DateTime(Min.Year, Min.Month, 1);
var Stop = new DateTime(Max.Year, Max.Month, 1).AddMonths(Max.Day == 1 ? 0 : 1);
while(curr < Stop)
{
yield return curr;
curr = curr.AddMonths(1);
}
}
public List<DataPoint> GetBacklogByMonth(DateTime min, DateTime max)
{
return EnumerateMonths(min, max)
.Select(m => new DataPoint
{
Date = m,
Count = DB.Items.Where(s => s.Create <= m.AddMonths(1) && (!s.Close.HasValue || s.Close.Value >= m.AddMonths(1)))
.Count()
}
).ToList();
}
qui fonctionne parfaitement, sauf que chaque Count
est une requête séparée de sorte que son super lent (un aller-retour pour chaque mois), donc ma question est de savoir comment pourrait Je restructurer cette requête pour le faire dans un aller-retour au serveur. Au départ, je pensais à faire une sorte de groupe par agrégat par mois, mais parce que chaque élément pourrait être «actif» dans de nombreux mois, je ne pense pas que cela fonctionnerait.
Des suggestions?
cela devrait fonctionner mais il est possible qu'il puisse tirer plusieurs milliers de lignes, cela peut être trop de trafic réseau. Mal essayer et voir si c'est acceptable. – luke
Si les lignes sont grandes, vous pouvez 'Select()' juste les colonnes 'Create' et' Close'. Une autre alternative, si vous utilisez MS SQL Sever, est de créer une fonction CLR qui fera le travail côté serveur. Vous pouvez ensuite ajouter cette fonction en tant que méthode dans votre mappage LINQ-to-SQL. http://msdn.microsoft.com/en-us/library/ms189876.aspx – Jay