2011-01-26 8 views
6

Tengo dos expresiones LINQ que creo que debería poder combinar en una sola.¿Existe alguna forma mejor de combinar estas dos expresiones de Linq?

Tengo una lista de referencias, cada una de las cuales hace referencia a varios elementos, y estoy tratando de determinar los artículos más populares. Cada referente envía una puntuación de voto única a un elemento al que se hace referencia. Es decir, la referencia 1 podría dar un voto de 0.2, y la referencia 2 podría dar un voto de 0.03.

Un simplificada clase Referrer:

class Referrer 
{ 
    public double VoteScore { get; private set; } 
    public List<int> Items { get; private set; } 
    public Referrer(double v) 
    { 
     VoteScore = v; 
     Items = new List<int>(); 
    } 
} 

Mis dos expresiones LINQ son:

var Votes = 
    from r in Referrers 
    from v in r.Items 
    select new { ItemNo = v, Vote = r.VoteScore }; 

Eso me da una lista:

ItemNo:1, Vote:0.2 
ItemNo:3, Vote:0.2 
ItemNo:1, Vote:0.03 

Ahora, puede agrupar, suma, y ordenar con mi segunda expresión:

var SortedByScore = 
    from v in Votes 
    group v by v.ItemNo into g 
    let score = g.Sum((v) => v.Vote) 
    orderby score descending 
    select new { ItemNo = g.Key, Score = score }; 

¿Es posible combinar esto en una sola expresión? Me di cuenta de que se pueden encadenar las expresiones, es decir:

var SortedByScore = 
    from v in 
     (from r in ActivatedReferrers 
     from v in r.Items 
     select new { ItemNo = v, Vote = r.VoteScore }) 
    group v by v.ItemNo into g 
    let score = g.Sum((v) => v.Vote) 
    orderby score descending 
    select new { ItemNo = g.Key, Score = score }; 

Pero eso no es realmente diferente de lo que ya tengo - es sólo la primera expresión de anidación dentro de la segunda. ¿Hay alguna otra forma de combinar las dos expresiones en una sola?

+0

Parece un modelo extraño para mí. ¿Un "referente" da el mismo puntaje de voto a cada artículo en su lista de artículos? Me encantaría saber qué estás modelando. – Pedro

+0

Piensa en cómo funciona PageRank. Eso no es lo que estoy construyendo, pero la idea es similar. Básicamente, cada referencia obtiene un puntaje de 1.0, y ese puntaje se distribuye de manera uniforme en todas las cosas de su lista. El modelo es simple, pero efectivo para lo que estoy haciendo. –

Respuesta

4

¿Qué tal:

from r in Referrers 
from v in r.Items 
group r.VoteScore by v into g 
let score = g.Sum() 
orderby score descending 
select new { ItemNo = g.Key, Score = score } 
+0

Eso parece ser lo que estaba buscando. Gracias. Ahora voy a estudiar la sintaxis de agrupación. Esto es tan simple que mi pérdida significa que no entiendo completamente la agrupación. –

+0

Ah, acabo de darme cuenta de lo que terminé con exactamente lo que tienes. Me concentré más en simplificar lo que Jim tenía y no me di cuenta de que 'Items' era en realidad' List 'que cambiaba cosas debido a la consulta anidada y la reutilización de la variable' v'. –

Cuestiones relacionadas