2011-11-04 6 views
5

J'ai un ensemble d'entités de publications avec une propriété ReleaseDate. Je voudrais obtenir une Liste de tous les combos mois-&-mois distincts de cet ensemble dans le but de créer un widget de pagination.Année-mois distinct avec Linq (aux entités)

De préférence, je voudrais une liste de valeurs DateTime avec le jour comme 1 pour chaque année mois distincte de mes publications, qui:

IEnumerable<DateTime> DistinctYearMonths = from p in context.Publications. .... ? 

Comment puis-je terminer ce LINQ-à-entités requête?

Répondre

12
IEnumerable<DateTime> DistinctYearMonths = context.Publications 
    .Select(p => new { p.ReleaseDate.Year, p.ReleaseDate.Month }) 
    .Distinct() 
    .ToList() // excutes query 
    .Select(x => new DateTime(x.Year, x.Month, 1)); // copy anonymous objects 
                // into DateTime in memory 

L'étape intermédiaire pour faire saillie dans un type anonyme est nécessaire, car on ne peut pas projeter directement dans un DateTime (constructeurs avec des paramètres ne sont pas pris en charge dans les projections de LINQ aux entités et les Year et Month propriétés de DateTime sont en lecture seule, donc vous ne pouvez pas les définir avec la syntaxe d'initialisation (new DateTime { Year = p.ReleaseDate.Year, ... } n'est pas possible)).

+0

Vous gagnez. Et +1 pour la bonne explication - toutes les autres réponses ici sont similaires en donnant le "System.NotSupportedException: seuls les constructeurs sans paramètres et les initialiseurs sont supportés dans LINQ to Entities." – Faust

2

Essayez la requête suivante:

(from p in publications 
select new DateTime(p.ReleaseDate.Year, p.ReleaseDate.Month, 1)).Distinct(); 
+0

Hmmm. Je reçois "System.NotSupportedException: Seuls les constructeurs et les initialiseurs sans paramètre sont pris en charge dans LINQ to Entities." quand je mets ça dans LinqPad - des idées là-dessus? – Faust

+0

FWIW cela fonctionne bien pour moi dans LinqPad –

+0

@Faust signifie que 'ReleaseDate' n'a pas été initialisé dans la propriété elle-même. c'est une bonne pratique pour initer vos propriétés POCO de type DateTime et List comme suit: 'public virtual Liste Followers {get; ensemble; } = new Liste (); 'et' public DateTime CreatedDate {get; ensemble; } = DateTime.UtcNow; ' – Korayem

0
var DistinctYearMonths = (from p in context.Publications 
          select new DateTime(p.ReleaseDate.Year, 
               p.ReleaseDate.Month, 
               1)).Distinct(); 
1

En utilisant Grouper par:

(from i in context.Publications 
group i by new { i.ReleaseDate.Year, i.ReleaseDate.Month } into g 
select g.Key).ToList().Select(i => new DateTime(i.Year, i.Month, 1)); 
0
var DistinctYearMonths = context.Publications 
    .Select(x => new DateTime(x.ReleaseDate.Year, x.ReleaseDate.Month, 1)) 
    .Distinct() 
    .ToList() 

J'aime enchaînées les méthodes de LINQ beaucoup mieux que la forme longue. Ils sont beaucoup plus faciles à lire IMO.