簡體   English   中英

Linq中的數據透視表

[英]Pivot table in Linq

我知道您不能直接在Linq中使用tSQL PIVOT函數,但是我無法獲得正確的Linq語法,因為我覺得這是一個簡單的轉換(我可以在直接的tSQL中完成此操作)

我需要采用以下數據集:

樞紐之前

並將其旋轉為: 后樞軸

有人可以用正確的Linq語法幫助我嗎?

這是我如何在tSQL中完成此操作(都使用PIVOT()而不是)

 Select piv.* from (
  select custom_data_key, custom_data_value from dbo.kb_article_custom_data cd
 inner join dbo.kb_article kb on cd.article_id = kb.article_id
 where (custom_data_key='article_problem' or custom_data_key = 'article_cause' or custom_data_key='article_solution') and article_number='AKB26'
 ) d
 pivot
 (max(custom_data_value) for custom_data_key in([article_problem],[article_cause], [article_solution])) piv;

-不使用PIVOT()

select 
 max(case when t.[custom_data_key]='article_problem' then t.[custom_data_value] end) as Article_problem,
  max(case when t.[custom_data_key]='article_cause' then t.[custom_data_value] end) as Article_cause,
   max(case when t.[custom_data_key]='article_solution' then t.[custom_data_value] end) as Article_solution
 from(select custom_data_key, custom_data_value from dbo.kb_article_custom_data cd
 inner join dbo.kb_article kb on cd.article_id = kb.article_id
 where (custom_data_key='article_problem' or custom_data_key = 'article_cause' or custom_data_key='article_solution') and article_number='AKB26')t

此LINQ語句將在上面的第一張圖片中為我提供結果:

var query = 
                        from a in custdata
                        join b in kbase on a.article_id equals b.article_id
                        where (a.custom_data_key == "article_problem" || a.custom_data_key == "article_cause" || a.custom_data_key == "article_solution") && b.article_number == id
                        select new { Key = a.custom_data_key, Value = a.custom_data_value };

這是失敗的地方。 我將上面的Linq查詢的結果作為-

var q2 = from row in  query
                     group row by "Value" into g
                     select new TO_Kbase
                     {
                         Problem= g.Where(c => c.Key =="article_problem" ).Select(c => c.Value).ToString(),
                         Cause = g.Where(c => c.Key =="article_cause").Select(c => c.Value).ToString(),
                         Solution = g.Where(c => c.Key =="article_solution").Select(c => c.Value).ToString()
                     };
            foreach(var x in q2)
            {
                TO_Kbase kb = new TO_Kbase();
                kb.Problem =x.Problem;
                kb.Cause = x.Cause;
                kb.Solution = x.Solution;
                ta.Add(kb);

            }

輸出是這樣的:

Problem: System.Data.Linq.SqlClient.Implementation.ObjectMaterializer`1+d__0`1[System.Data.SqlClient.SqlDataReader,System.String] 
Cause: System.Data.Linq.SqlClient.Implementation.ObjectMaterializer`1+d__0`1[System.Data.SqlClient.SqlDataReader,System.String] 
Solution: System.Data.Linq.SqlClient.Implementation.ObjectMaterializer`1+d__0`1[System.Data.SqlClient.SqlDataReader,System.String]

如果我正確理解了您的數據結構,則可以執行與“不使用PIVOT()” T-SQL查詢非常相似的操作:

// Test data.
var kb_article_custom_data = new CustomData[] {
    new CustomData() { article_id = 1, custom_data_key = "article_problem", custom_data_value = "when you try ... 1"},
    new CustomData() { article_id = 1, custom_data_key = "article_cause", custom_data_value = "the issues may occur ... 1"},
    new CustomData() { article_id = 1, custom_data_key = "article_solution", custom_data_value = "1. Click start, then ... 1"},
    new CustomData() { article_id = 2, custom_data_key = "article_problem", custom_data_value = "when you try ... 2"},
    new CustomData() { article_id = 2, custom_data_key = "article_cause", custom_data_value = "the issues may occur ... 2"},
    new CustomData() { article_id = 2, custom_data_key = "article_solution", custom_data_value = "1. Click start, then ... 2"},
    new CustomData() { article_id = 3, custom_data_key = "article_problem", custom_data_value = "when you try ... 3"},
    //new CustomData() { article_id = 3, custom_data_key = "article_cause", custom_data_value = "the issues may occur ... 3"},
    new CustomData() { article_id = 3, custom_data_key = "article_solution", custom_data_value = "1. Click start, then ... 3"},
};

var kb_article = new Article[] {
    new Article() { article_id = 1, article_title = "Title ... 1"},
    new Article() { article_id = 2, article_title = "Title ... 2"},
    new Article() { article_id = 3, article_title = "Title ... 3"},
};

// Query resembling your "without pivot" query.
var result =
    from article in kb_article
    join custom in kb_article_custom_data on article.article_id equals custom.article_id into ac
    select new {
        id = article.article_id,
        title = article.article_title,
        problem = ac.Where(x => x.custom_data_key == "article_problem").Select(x => x.custom_data_value).FirstOrDefault(x => x != null),
        cause = ac.Where(x => x.custom_data_key == "article_cause").Select(x => x.custom_data_value).FirstOrDefault(x => x != null),
        solution = ac.Where(x => x.custom_data_key == "article_solution").Select(x => x.custom_data_value).FirstOrDefault(x => x != null)
    };

foreach (var r in result)
    Console.WriteLine(r);

產生以下輸出:

{ id = 1, title = Title ... 1, problem = when you try ... 1, cause = the issues may occur ... 1, solution = 1. Click start, then ... 1 }
{ id = 2, title = Title ... 2, problem = when you try ... 2, cause = the issues may occur ... 2, solution = 1. Click start, then ... 2 }
{ id = 3, title = Title ... 3, problem = when you try ... 3, cause = , solution = 1. Click start, then ... 3 }

如果article_id特定的article_id進行過濾,則需要添加where子句:

var id = 1;
var result =
    from article in kb_article
    where article.article_id == id
    join custom in kb_article_custom_data on article.article_id equals custom.article_id into ac
    select new
    {
        id = article.article_id,
        title = article.article_title,
        problem = ac.Where(x => x.custom_data_key == "article_problem").Select(x => x.custom_data_value).FirstOrDefault(x => x != null),
        cause = ac.Where(x => x.custom_data_key == "article_cause").Select(x => x.custom_data_value).FirstOrDefault(x => x != null),
        solution = ac.Where(x => x.custom_data_key == "article_solution").Select(x => x.custom_data_value).FirstOrDefault(x => x != null)
    };

產生以下輸出:

{ id = 1, title = Title ... 1, problem = when you try ... 1, cause = the issues may occur ... 1, solution = 1. Click start, then ... 1 }

解:

 var query =
                        from a in custdata
                        join b in kbase on a.article_id equals b.article_id into ac
                        where (a.custom_data_key == "article_problem" || a.custom_data_key == "article_cause" || a.custom_data_key == "article_solution") && a.article_id == id
                        group a by new { a.article_id} into abc
                        select new
                        {
                            ID = abc.Key.article_id,
                            Cause = abc.Where(a =>a.custom_data_key == "article_cause").Select(a => a.custom_data_value).FirstOrDefault(x => x != null),
                            Problem = abc.Where(a => a.custom_data_key == "article_problem").Select(a => a.custom_data_value).FirstOrDefault(x => x != null),
                            Solution = abc.Where(a => a.custom_data_key == "article_solution").Select(a => a.custom_data_value).FirstOrDefault(x => x != null)
                        };

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM