Как вращать данные путем преобразования строк в столбцы с помощью LINQ - PullRequest
2 голосов
/ 07 февраля 2011

Я написал следующий запрос для поворота данных путем преобразования строк в столбцы с использованием LINQ:

var query = from p in context.PrivilegesTable
            group p by p.Type into g
            select new Privileges
            {
                Type = g.Key,
                AllowRead = g.Any(p => p.Seq == 1),
                AllowAdd = g.Any(p => p.Seq == 2)
                AllowEdit = g.Any(p => p.Seq == 3)
                AllowDelete = g.Any(p => p.Seq == 4)
            };

Я думаю, что есть лучший способ реализовать это.для получения более подробной информации прочитайте следующее:

У меня есть следующая таблица привилегий:

      Type    Seq
        1       1
        2       1
        2       2
        3       1
        3       2
        3       3

И следующий класс привилегий:

class Privileges
{
   public int ID { get; set; }

   public Type Type { get; set;}

   public int AllowRead { get; set; } // when sequence = 1 
   public int AllowAdd { get; set; } // when sequence = 2
   public int AllowEdit { get; set; } // when sequence = 3
   public int AllowDelete { get; set; } // when sequence = 4
}

Теперь я хочусоздайте List<Prvileges>, используя LINQ, чтобы получить следующий результат:

[Type, AllowRead, AllowAdd, AllowEdit, AllowDelete]

[1, True, False, False, False]

[2, True, True, False, False]

[3, True, True, True, False]

Мой запрос плохо влияет на производительность?Есть ли лучший?

Ответы [ 2 ]

0 голосов
/ 09 февраля 2011

Ваш запрос будет ужасным, потому что каждый Any делает соединение (проблема реализации L2S). В SQL вы бы сделали пункт сводки. Это может быть смоделировано в L2S, но проблема соединения остается (я сообщил об этой ошибке сегодня при подключении). Извините, мне нечем обойтись. Если проблема в perf, вы должны кэшировать или использовать raw sql.

Редактировать: Я думаю, что нашел для вас особый случай:

var query = from p in context.PrivilegesTable
            let shift = 1 << p.Seq
            group shift by p.Type into g
            select new
            {
                Type = g.Key,
                AllowMask = g.Sum(),
            };

Насколько это круто? ;-) К ​​сожалению, это ужасный код, который работает только до 64-битных флагов.

0 голосов
/ 07 февраля 2011

Я бы предложил использовать enum для представления привилегий, которые вы можете иметь.

[Flags]
enum Privilege
{
    None = 0,
    Read = 1,
    Add = 2,
    Edit = 4,
    Delete = 8,
}

Таким образом, вы можете хранить одно значение для представления всех ваших привилегий. Тогда ваш класс привилегий будет выглядеть так:

class Privileges {
    public int ID { get; set; }
    public Type Type { get; set;}
    private Privilege m_Privileges;

    public bool AllowRead {
        get { return HasPrivilege(Privilege.Read); }
        set { CheckPrivilege(Privilege.Read, value); }
    }

    public bool AllowAdd {
        get { return HasPrivilege(Privilege.Add); }
        set { CheckPrivilege(Privilege.Add, value); }
    }

    public bool AllowEdit {
        get { return HasPrivilege(Privilege.Edit); }
        set { CheckPrivilege(Privilege.Edit, value); }
    }

    public bool AllowDelete {
        get { return HasPrivilege(Privilege.Delete); }
        set { CheckPrivilege(Privilege.Delete, value); }
    }

    private bool HasPrivilege(Privilege p) {
        return (m_Privileges & p) == p;
    }

    private void CheckPrivilege(Privilege p, bool owns) {
        if (owns)
            m_Privileges = m_Privileges | p;
        else
            m_Privileges = m_Privileges & (~p);
    }
}

Конечно, этот подход действителен, только если у вас есть ограниченное и известное количество привилегий.

Надеюсь, что поможет

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