Группировать по в linq + выберите - PullRequest
1 голос
/ 21 марта 2011

говорят, что у меня есть эти данные

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
    }

Я хочу сгруппировать все 3 строки по courseId (или префиксу), а затем взять эту информацию и сделать из нее класс

Таким образом, конечный результат будет

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 голосов
/ 23 марта 2011

Вот подход, который я считаю достаточно функциональным.

Сначала настройте словарь действий, который установит соответствующее разрешение курса с учетом идентификатора уровня разрешения.

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

Теперь создайтефункция, которая преобразует префикс курса и список идентификаторов уровней разрешений в новый 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();

Как это работает для вас?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...