加入会员表

时间:2010-11-25 23:13:05

标签: asp.net sql linq entity-framework

为什么Microsoft仅对一个表使用带有GroupBy子句的愚蠢示例?

http://msdn.microsoft.com/en-us/library/bb896341.aspx

当我尝试选择一些不在GroupBy中的字段时,为什么会出错? 错误表示不在GroupBy子句中的字段在当前上下文中不存在。

using (Entities db = new Entities())
{
    var query = "SELECT RLS.RoleId, UIR.UserId, UIR.RoleId, USR.UserName FROM Entities.aspnet_Roles AS RLS " +
                 "INNER JOIN Entities.vw_aspnet_UsersInRoles AS UIR " +
                 "ON RLS.RoleId = UIR.RoleId " + 
                 "INNER JOIN Entities.aspnet_Users AS USR " + 
                 "ON UIR.UserId = USR.UserId " + 
                 //"GROUP BY RLS.RoleId"  // is uncomment - it says UserId doesn't exist in context
                 ;
    var x = new ObjectQuery<DbDataRecord>(query, db);
    var y = x.ToTraceString().Replace("\n", " ").Replace("\t", " ").Replace("\r", " ");
}

LINQ也一样:

var x = from RLS in db.aspnet_Roles
                        join URS in db.vw_aspnet_UsersInRoles
                        on RLS.RoleId equals URS.RoleId
                        join USR in db.aspnet_Users
                        on URS.UserId equals USR.UserId
                        group RLS by RLS.RoleId into GRP
                        select new
                        {
                            GRP.Key
                        };

问题是:如何只选择一个字段来选择所有字段和GroupBy选择?

提前致谢。

3 个答案:

答案 0 :(得分:3)

GROUP BY子句中不包含的所有字段都必须是汇总表达式,例如AVG(...)SUM(...)MAX(...)等。

所以这是错误的:

SELECT RLS.RoleId, UIR.UserId, UIR.RoleId, USR.UserName
(...)
GROUP BY RLS.RoleId

因为SELECT中的最后三个表达式应该以某种方式聚合或添加到GROUP BY子句中。

这是合乎逻辑的,因为通过指定GROUP BY RLS.RoleId,您说RLS.RoleId在最终结果中应该是唯一的,因此每个值只有一行。但是对于每个RLS.RoleID,UIR.UserId,UIR.RoleId或USR.UserName可能有多个值。因此,您需要告诉DBMS如何将它们组成一行:average,maximum,minimum ......或者您将字段添加到GROUP BY子句中,以便不是RLS.RoleID而是组合example。

答案 1 :(得分:1)

我没有看到您发布的查询中使用的任何聚合函数(COUNT,SUM,AVG等)。因此,不需要包含GROUP BY表达式,并且没有理由这样做。你能解释一下你想要完成什么吗?

答案 2 :(得分:0)

我想我不明白 littlegreen 。 他的建议确实有帮助......虽然我对SQL Server与MySQL比较感到不安(有足够的设置一个分组字段)。

作品!

SELECT DISTINCT 
   RLS.RoleId, 
   COUNT(RLS.RoleId) AS RID_CNT, 
   MAX(CAST(UIR.UserId AS VARCHAR(36))) AS EXPR1, 
   MAX(CAST(USR.UserName AS VARCHAR(36))) AS EXPR2
FROM aspnet_Roles AS RLS 
INNER JOIN vw_aspnet_UsersInRoles AS UIR ON RLS.RoleId = UIR.RoleId 
INNER JOIN aspnet_Users AS USR ON UIR.UserId = USR.UserId
GROUP BY RLS.RoleId