【问题标题】:LINQ partial crosstab query when the potential columns are not fixed潜在列不固定时的 LINQ 部分交叉表查询
【发布时间】:2012-10-30 05:26:09
【问题描述】:

我需要生成用于导出的“扁平化”数据版本,客户希望相关的表行显示为列。我们正在使用实体框架 4 和 .NET 4.0

客户可以为其活动创建自定义问题。可能有零到无限的问题。参加活动的用户可能不回答、部分或全部这些问题。

我需要制作的是这样的:

User 1    User 1 info field A   User 1 info field B    User 1 Answer to question A    User 1 Answer to Question B
User 2    User 2 info field A   User 2 info field B    User 2 Answer to question A    User 2 Answer to Question B

创建结果集的用户信息部分不是问题,但我对如何获取相关问题和答案感到困惑,即:

from urf in tblUserRegistrationFields.Include("tblRegistrationFields")
where urf.UserID == eachUserID && urf.tblRegistrationField.EventID == thisEventID
select new
{
    FieldLabel = urf.tblRegistrationField.FieldLabel, //this is the question name
    value = urf.value //this is the user's answer
}

并将这些作为单独的列添加到我的用户选择语句中,即:

var users = from u in context.tblUsers
            <snip>
            select new
            {
                UserID = u.UserID,
                <snip>,
                CustomQuestionA = AnswerA,
                CustomQuestionB = AnswerB,
                ... etc.
            };

最终我需要创建一个网格,然后我可以将其导出为所需的格式,并且我对非 LINQ 解决方案持开放态度(尽管购买 3rd 方控件不是一种选择。)我怀疑有一种方法可以利用 LINQ 的分组功能,但我无法将其应用于此场景。

【问题讨论】:

    标签: linq entity-framework linq-to-entities


    【解决方案1】:

    我找到了一种在 SQL 中进行动态数据透视的方法,但无法让它与 两个 相关的表一起工作,只有一个。动态 SQL 枢轴点在这里: http://www.simple-talk.com/blogs/2007/09/14/pivots-with-dynamic-columns-in-sql-server-2005/

    最终,我退回并手动创建了一个数据集。这当然不是一个优化的解决方案,但它为客户提供了他们想要的东西。对于大量数据,我不推荐这种方法。

    我创建了数据集和数据表的固定列,然后遍历问题列表:

    //get the list of questions
    var context = new EventRegistrationEntities();
    var customQuestions = from rf in context.tblRegistrationFields
                          where rf.EventID == vEventID
                          select new
                          {
                              RegistrationFieldID = rf.RegistrationFieldID,
                              FieldLabel = rf.FieldLabel
                          };
    
    //add a question column for each question
    List<string> extracolumns = new List<string>();
    
    foreach (var q in customQuestions)
    {
        dt.Columns.Add(q.FieldLabel, typeof(string));
    
        //store the question names for later user
        extracolumns.Add(q.RegistrationFieldID.ToString() + "-" + q.FieldLabel.ToString());
    }
    

    接下来,我循环遍历用户列表并插入固定数据,然后在该循​​环中(呃)添加用户的答案:

    foreach (var c in extracolumns) //these are the custom *questions*
    {
        int regID = Convert.ToInt32(c.Substring(0, c.IndexOf("-")));
        string question = c.Substring(c.IndexOf("-") + 1); //we need to pass the question text (aka column header) in because if the user hasn't answered the question we have no access to it from here
    
        //get the question answer
        var userAnswer = (from urf in context.tblUserRegistrationFields.Include("tblRegistrationFields")
                          where urf.UserID == u.UserID && urf.RegistrationFieldID == regID
                          select new
                          {
                              Question = urf.tblRegistrationField.FieldLabel,
                              Answer = urf.value
                          }).FirstOrDefault();
    
         //add the answer to the data row
         if (userAnswer != null)
         {
             dr[question] = userAnswer.Answer.ToString();
         }
         else
         {
             dr[question] = ""; //if the user has not answered the question, insert a blank
         }
     }
    

    【讨论】:

      猜你喜欢
      • 2012-09-11
      • 1970-01-01
      • 1970-01-01
      • 2010-10-30
      • 2011-03-01
      • 2014-10-23
      • 2017-03-06
      • 2010-10-13
      相关资源
      最近更新 更多