分组在linq + select

时间:2011-03-20 21:57:51

标签: c# linq nhibernate

说我有这个数据

1   757f27a2-e997-44f8-b2c2-6c0fd6ee2c2f    2   3
2   757f27a2-e997-44f8-b2c2-6c0fd6ee2c2f    3   1
3   757f27a2-e997-44f8-b2c2-6c0fd6ee2c2f    2   2

column 1 // pk
column 2 // userId
column 3 // courseId
column 4 // permissionId

我有这个班级

class CoursePermissions
    {
        public string Prefix { get; set; }
        public bool OwnerPermission { get; set; } // permissionId 1
        public bool AddPermission { get; set; } // permissionId 2
        public bool EditPermission { get; set; } // permissionId 3
    }

我想通过courseId(或Prefix)对所有3行进行分组,然后获取该信息并从中创建一个类

所以最终的结果是

List<CoursePermissions> permissions = new List<CoursePermissions>();

CoursePermissions a = new CoursePermissions
{
   Prefix = "comp101";
   OwnerPermission = false,
   AddPermission  = true,
   EditPermission = true
};


CoursePermissions b = new CoursePermissions
{
   Prefix = "comp102";
   OwnerPermission = true,
   AddPermission  = false,
   EditPermission = false 
};

permissions.Add(a);
permissions.Add(b);

所以上面是如果我从数据库中获取所有行数据并手动按照我想要的方式查看对象的样子。当然,我需要以某种方式进行查询。

在我的例子中,我有2名学生。他们都属于同一个课程。学生1编辑和添加Comp101的权限,但只有comp102的所有者权限。

我希望将所有行返回Comp101并将其放入CoursePermissions。然后我想为Comp102返回所有行并将其放入CoursePermissions。然后将所有这些存储在一个集合中并使用它们。

我唯一能做的就是这样的事情

 var list = session.Query<PermissionLevel>().Where(u => u.Student.StudentId == studentId).ToList();

            IEnumerable<IGrouping<string, PermissionLevel>> test = list.GroupBy(x => x.Course.Prefix);

            foreach (var t in test)
            {
                CoursePermissions c = new CoursePermissions();

                foreach (var permissionLevel in t)
                {
                    if (permissionLevel.PermissionLevelId == 1)
                    {
                        c.OwnerPermission = true;
                    }
                }
            }

如果我可以摆脱每个循环的嵌套并且在数据来自查询时全部完成,那就太好了。

1 个答案:

答案 0 :(得分:0)

我认为这是一种非常实用的方法。

首先设置一个动作字典,在给定权限级别id的情况下设置相应的课程权限。

var setPermission = new Dictionary<int, Action<CoursePermissions>>()
{
    { 1, cps => cps.OwnerPermission = true },
    { 2, cps => cps.AddPermission = true },
    { 3, cps => cps.EditPermission = true },
};

现在创建一个函数,将课程前缀和权限级别ID列表转换为新的CoursePermissions对象。

Func<string, IEnumerable<int>, CoursePermissions>
    buildCoursePermission = (prefix, permissionLevelIds) =>
    {
        var cps = new CoursePermissions() { Prefix = prefix };
        foreach (var permissionLevelId in permissionLevelIds)
        {
            setPermission[permissionLevelId](cps);
        }
        return cps;
    };

现在你剩下的就是一个简单的查询,它将你的权限级别列表转换为课程权限列表。

var coursePermissionsList =
    (from pl in list
     group pl.PermissionLevelId by pl.Course.Prefix into gcpls
     select buildCoursePermission(gcpls.Key, gcpls)).ToList();

这对你有什么用?