2011-02-07 33 views
2

列旋轉數據我寫了下面的查詢按行轉換爲使用LINQ列旋轉數據:如何通過行轉換爲使用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 
} 

現在,我想創建一個使用LINQ到List<Prvileges>有以下結果:

[Type,AllowRead,AllowAdd,AllowEdit,AllowDelete]

[1,真,假,假,假]

[2,真,真,假,假]

[3,真,真,真,假]

是我的查詢性能不好? 有更好的嗎?

回答

0

我建議使用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); 
    } 
} 

當然,如果你有權限有限的已知數量的這種方法纔有效。

希望幫助

+0

感謝您的答案,但數據存儲,我只想編寫最好的LINQ查詢來閱讀它。 – Homam 2011-02-07 17:21:49

0

你的查詢性能將是糟糕的,因爲每個任何做了一個連接(L2S實現問題)。在SQL中你會做一個pivot子句。它可以在L2S中模擬,但連接問題仍然存在(我今天在連接上報告了這個錯誤)。我的知識沒有解決方法,對不起。如果perf是一個問題,你必須緩存或使用原始的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

您確定無法通過2 .Select()避免多個連接? – Guillaume86 2011-02-08 22:56:09