C# 将聚合结果分配给实体属性,但不提取所有子查询行

C# 将聚合结果分配给实体属性,但不提取所有子查询行,c#,sql,linq,C#,Sql,Linq,我有一个评论和投票相关的评论 [Table("QAComment")] public class QaComment : IEntity { [Key, Column("QACommentID")] public int Id { get; set; } // ... public virtual ICollection<QaCommentVote> Votes { get; set; } [NotMapped] public i

我有一个评论和投票相关的评论

[Table("QAComment")]
public class QaComment : IEntity
{
    [Key, Column("QACommentID")]
    public int Id { get; set; }

    // ...

    public virtual ICollection<QaCommentVote> Votes { get; set; }

    [NotMapped]
    public int OverallVote { get; set; }
}

[Table("QACommentVote")]
public class QaCommentVote : IEntity
{
    [Key, Column("QACommentVoteID")]
    public int Id { get; set; }

    [ForeignKey("QAComment")]
    public int QaCommentId { get; set; }

    public int Value { get; set; }

    public virtual QaComment QaComment { get; set; }
}

您可以将
qacoment
和要单独查找的总和作为匿名类型获取,并使用LINQ to Objects将它们合并到一个对象中:

var comments
    = Set<QaComment>()
      .Select(c => new { c, sum = c.Votes.Sum(v => v.Value))
      .AsEnumerable() // to make next query execute as LINQ to Objects query
      .Select(x => { x.c.OverallVote = x.sum; return x.c; })
      .ToList();
var注释
=集合()
.Select(c=>new{c,sum=c.vows.sum(v=>v.Value))
.AsEnumerable()//使下一个查询作为LINQ to Objects查询执行
.Select(x=>{x.c.OverallVote=x.sum;返回x.c;})
.ToList();

但要明确一点:我还没有测试过:)

谢谢,这是个好主意。你认为这个“选择(x=>{x.c.OverallVote=x.sum;返回x.c;}”吗不会在纯IQueryable上工作?好的,将检查它…不,我认为不会。首先,因为编译器无法将其转换为表达式。Lambda只能在单行时通过编译转换为表达式(不使用
{
/
}
)你必须提供
Expression
作为
IQueryable
参数。但即使可以,我也不认为有一个SQL可以从这样的表达式生成。我想我更喜欢将其作为扩展方法,因为我需要在我的应用程序中的许多地方使用此代码。如果没有更好的答案,我会接受它e、 现在升级投票。稍晚一点还没有测试。请查看我的更新,这是我想要的LINQ结果。发现了一个类似的问题:看起来没有办法像我想要的那样完成。你可以使用AutoMapper进行这些类型的聚合。你所需要的只是一个类,它将包含你从
qacoment ,比如说
qacomentinfo
。如果
qacomentinfo
属性
VotesCount
,AutoMapper将创建一个包含计数的查询。
SELECT 
    qac.*, 
    (SELECT SUM(v.Value)
     FROM QACommentVote v 
     WHERE v.QACommentID = qac.QACommentID) as OverallVote
FROM QAComment qac
var comments
    = Set<QaComment>()
      .Select(c => new { c, sum = c.Votes.Sum(v => v.Value))
      .AsEnumerable() // to make next query execute as LINQ to Objects query
      .Select(x => { x.c.OverallVote = x.sum; return x.c; })
      .ToList();