2017-08-22 6 views
1

J'ai une table:LINQ somme de sélection de requête compilé plusieurs colonnes

ForObjectTypeID (short, PK) 
ForObjectID (int, PK) 
UserID (int, PK) 
Upvote (bool) 
ShadowBannedVote (bool) 

Étant donnée une, je souhaite ObjectTypeID et ObjectID retourner un Tuple<int, int, int> où les valeurs respectives sont les suivantes:

  • Total des votes: Nombre total d'enregistrements où ShadowBannedVote == false
  • Total des Upvotes: Nombre total d'enregistrements où Upvote == true && ShadowBannedVote == false
  • totale Ombre Banned Votes: Nombre total d'enregistrements où ShadowBannedVote == true

Il doit être une seule requête compilée, pas fractionnés en plusieurs requêtes. C'est aussi loin que je l'ai eu, je ne peux pas calculer comment effectuer les sommes et les comptes dans la valeur de retour.

public static readonly Func<DBContext, ObjectType, int, Tuple<int, int, int>> GetTotalVotes = CompiledQuery.Compile(
    (DBContext db, ObjectType forObjectType, int forObjectID) => 
    db.UserVotes.Where(c => c.ForObjectTypeID == (short)forObjectType && c.ForObjectID == forObjectID) 
    .Select(c=> new {c.Upvote, c.ShadowBannedVote}).Select(c=> new Tuple<int, int, in>(0, 0, 0))); 

Répondre

0

sera intéressant de voir si cela est possible, mais une solution serait:

public static readonly Func<DBContext, ObjectType, int, IEnumerable<Tuple<bool, bool>>> GetTotalVotes = CompiledQuery.Compile(
    (DBContext db, ObjectType forObjectType, int forObjectID) => 
    db.UserVotes.Where(c => c.ForObjectTypeID == (short)forObjectType && c.ForObjectID == forObjectID) 
    .Select(c=> new Tuple<bool, bool>(c.Upvote, c.ShadowBannedVote))); 

Et puis travailler tout simplement les chiffres dans la logique de l'application.

0

Vous pouvez essayer de grouper par une constante, la sommation et en prenant le résultat, à savoir quelque chose comme

public static readonly Func<DBContext, ObjectType, int, Tuple<int, int, int>> GetTotalVotes = CompiledQuery.Compile(
     (DBContext db, ObjectType forObjectType, int forObjectID) 
    => 
    db.UserVotes 
    .Where(c => c.ForObjectTypeID == (short)forObjectType 
      && c.ForObjectID == forObjectID) 
    .Select(c => new { c.Upvote, c.ShadowBannedVote }) 
    .GroupBy(c => 1) 
    .Select(c => new Tuple<int, int, int>(
     c.Count(r => !r.ShadowBannedVote), 
     c.Count(r => r.Upvote && !r.ShadowBannedVote), 
     c.Count(r => r.ShadowBannedVote) 
    )).Single());