2011-11-04 14 views
5

Tengo un conjunto de entidades de Publicaciones con una propiedad ReleaseDate. Me gustaría obtener una lista de todos los años distintos: & -month combos de este conjunto con el fin de crear un widget de paginación.Distintos meses-año con Linq (a entidades)

Preferiblemente, me gustaría una lista de valores DateTime con el día 1 como para cada año-mes distinto de mis publicaciones establecen:

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

Como puedo terminar esta consulta LINQ a las entidades?

Respuesta

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 

El paso intermedio para proyectarse en un tipo anónimo es necesario porque no se puede proyectar directamente en un DateTime (constructores con parámetros no se admiten en proyecciones en LINQ a las entidades y las Year y Month propiedades de DateTime son de sólo lectura, por lo que no puede configurarlos con la sintaxis del inicializador (new DateTime { Year = p.ReleaseDate.Year, ... } no es posible)).

+0

Usted gana. Y +1 para la buena explicación: todas las demás respuestas aquí son similares al producir "System.NotSupportedException: solo los constructores sin parámetros y los inicializadores son compatibles con LINQ to Entities". – Faust

2

Pruebe la siguiente consulta:

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

Hmmm. Obtengo "System.NotSupportedException: solo los constructores y los inicializadores sin parámetros son compatibles con LINQ to Entities". cuando puse esto en LinqPad, ¿alguna reflexión sobre eso? – Faust

+0

FWIW esto funciona bien para mí en LinqPad –

+0

@Faust significa que 'ReleaseDate' no se inicializó en la propiedad en sí. es una buena práctica iniciar sus propiedades POCO de tipo DateTime y List de la siguiente manera: 'public virtual List Seguidores {get; conjunto; } = new List (); 'y' public DateTime CreatedDate {get; conjunto; } = DateTime.UtcNow; ' – Korayem

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

Usando Agrupar por:

(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() 

me gusta métodos LINQ encadenados mucho mejor que la forma larga. Son mucho más fáciles de leer IMO.