【问题标题】:LINQ Left Join -Where statement issueLINQ Left Join -Where 语句问题
【发布时间】:2014-03-06 04:22:52
【问题描述】:

有点想出了我原来的问题(尽管如果有更好的方法我很想听听)。我现在遇到了 Where 子句的问题

where answer.TeacherID == "1234"

我需要所有 7 行来返回不仅仅是具有 TeacherID 的 4 行。在我当前的语句(如下)中,无论我把 Where 它总是只返回 4 行......我做错了什么?

这是我更新的 LINQ 语句(仍然需要 Where 子句)

var resultSet = (from question in db.Questions
                 join TeacherDetail in db.AnswerDetails on question.QuestionID 
                 equals TeacherDetail.QuestionID into qListTeacher
                 from TeacherDetail in qListTeacher.DefaultIfEmpty()
                 join answer in db.Answers on TeacherDetail.AnswerKey 
                 equals answer.AnswerKey into aList
                 from answer in aList.DefaultIfEmpty()
                 join LeaderDetail in db.AnswerDetails on question.QuestionID 
                 equals LeaderDetail.QuestionID
                 into qListLeader
                 from LeaderDetail in qListLeader.DefaultIfEmpty()
                 select new ProfessionalObject
                 {
                     QuestionID = question.QuestionID,
                     IndicatorID = question.ID,
                     QuestionDescription = question.Description,
                     AnswerKey = answer.AnswerKey,
                     TeacherID = answer.TeacherID,
                     LeaderID = answer.LeaderID,
                     StatusKey = answer.StatusKey,
                     TeacherAnswerDetailKey = (answer.TeacherID != null ? TeacherDetail.AnswerDetailKey : 0),
                     TeacherAnswerOptionKey = (answer.TeacherID != null ? TeacherDetail.AnswerOptionKey : 0),
                     TeacherComment = (answer.LeaderDPSID == null ? TeacherDetail.Comment : ""),
                     LeaderAnswerDetailKey = (answer.LeaderID != null ? LeaderDetail.AnswerDetailKey : 0),
                     LeaderAnswerOptionKey = (answer.LeaderID != null ? LeaderDetail.AnswerOptionKey : 0),
                     LeaderComment = (answer.LeaderDPSID != null ? LeaderDetail.Comment : ""),                                 
                     }).ToList();

无论是否有答案,我都想将问题打包到我的对象中。 我有一位领导和一位老师有能力回答这些问题

所以我想要一个返回所有问题的结果集,并且我希望教师评论进入教师属性 和领导者评论进入领导者属性。

例如:

QuestionID: 1, QuestionDescription: Question 1, TeacherComment = Null, LeaderComment = "Leader Answer" , TeacherID: 12345, LeaderID: 9999
QuestionID: 2, QuestionDescription: Question 2, TeacherComment = Null, LeaderComment = "Leader Answer 2", TeacherID: 12345, LeaderID: 9999
QuestionID: 3, QuestionDescription: Question 3, TeacherComment = "Teacher Answer", LeaderComment = NULL , TeacherID: 12345, LeaderID: NULL
QuestionID: 4, QuestionDescription: Question 4, TeacherComment = "Teacher Answer 2", LeaderComment = NULL , TeacherID: 12345, LeaderID: NULL
QuestionID 5, QuestionDescription: Question 5, TeacherComment = NULL, LeaderComment = NULL , TeacherID: NULL,  LeaderID: NULL
QuestionID 6, QuestionDescription: Question 6, TeacherComment = NULL, LeaderComment  = NULL , TeacherID: NULL,  LeaderID: NULL
QuestionID 7, QuestionDescription: Question 7, TeacherComment = NULL, LeaderComment = NULL, TeacherID: NULL,  LeaderID: NULL

Answer 表的 AnswerKey 上有一个 PK,还有一个 TeacherID 和一个 LeaderID AnswerDetail 表包含 QuestionID 和对问题的评论。

我尝试添加 where 语句来拆分教师信息(即 Where TeacherID != NULL 和 LeaderID == NULL 以及领导信息(TeacherID != NULL 和 LeaderID !=NULL)。但他们只是限制了我的结果集

答题记录:

AnswerKey: 1 TeacherID: 1234 LeaderID: 9999

AnswerKey: 5 TeacherID: 1234 LeaderID: NULL

AnswerDetail 记录:

AnswerKey: 1 QuestionID: 1 Comment: Leader Answer

AnswerKey: 1 QuestionID: 2 Comment: Leader Answer 2

AnswerKey: 5 Question: 3 Comment: Teacher Answer

AnswerKey: 5 Question: 4 Comment: Teacher Answer 2

问题记录:

QuestionID: 1 QuestionDescription: Question #1

QuestionID: 2 QuestionDescription: Question #2

QuestionID: 3 QuestionDescription: Question #3

QuestionID: 4 QuestionDescription: Question #4

QuestionID: 5 QuestionDescription: Question #5

QuestionID: 6 QuestionDescription: Question #6

QuestionID: 7 QuestionDescription: Question #7

更新:

上述结果集正确返回了 7 个问题,并且 Comments 在技术上是正确的。我希望实现的是,如果领导者有 cmets,那么我希望他们进入领导者属性,如果老师有 cmets,那么我希望他们进入教师属性。

Leader 的逻辑是如果 TeacherID != NULL 和 LeaderID != NULL 教师的逻辑是如果 TeacherID != NULL 和 LeaderID == NULL

这是我的课:

public class ProfessionalObject
{
    public int? QuestionID { get; set; }
    public string IndicatorID { get; set; }
    public string QuestionDescription { get; set; }
    public int? AnswerKey { get; set; }
    public string TeacherID { get; set; }
    public string LeaderID { get; set; }
    public int? StatusKey { get; set; }
    public int? TeacherAnswerDetailKey { get; set; }
    public int? TeacherAnswerOptionKey { get; set; }
    public string TeacherComment { get; set; }
    public int? LeaderAnswerDetailKey { get; set; }
    public int? LeaderAnswerOptionKey { get; set; }
    public string LeaderComment { get; set; }

    public ProfessionalObject()
    {
        QuestionID = 0;
        IndicatorID = "";
        QuestionDescription = "";
        AnswerKey = 0;
        TeacherID = "";
        LeaderID = "";
        StatusKey = 0;
        TeacherAnswerDetailKey = 0;
        TeacherAnswerOptionKey = 0;
        TeacherComment = "";
        LeaderAnswerDetailKey = 0;
        LeaderAnswerOptionKey = 0;
        LeaderComment = "";
    }
}

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    Where 就是这样做的。从所有不符合条件的数据中过滤集合。

    如果您不想过滤掉这些项目,您可以删除 where

    【讨论】:

    • 我需要它更像是左连接类型的东西。我知道 where 子句会过滤掉行,但我需要没有 cmets 的问题也出现在我的结果集中
    • 在我的问题中,您将看到我正在寻找的结果集的“示例”。
    • 我会给你建议,因为这样大的查询很难调试和理解(尤其是如果你像我一样在打电话)。创建多个简单查询,每个查询都会从某个来源检索特定数据 - 然后将它们组合成合适的查询(当我靠近计算机时,我会更仔细地查看您的查询)
    • 实际上你的分手评论让我走上了正确的道路。
    • 您还需要帮助吗?
    【解决方案2】:

    我最终使用@ShlomiBorovitz 的建议来分解我的作品并在最后加入它们:

    var questionSet = ( from question in Questions select question);
    var TeacherAnswer = ( from detail in AnswerDetails 
                        join answer in Answers on detail.AnswerKey equals answer.AnswerKey
                        where answer.TeacherID == "12345" && answer.LeaderID == null
                        select new { detail, answer});
    
    var LeaderAnswer = (from detail in AnswerDetails 
                        join answer in Answers on detail.AnswerKey equals answer.AnswerKey
                        where answer.TeacherID == "12345" && answer.LeaderID != null
                        select new { detail, answer});                                       
    
    
    
    var combination = ( from q in questionSet
                        join tDetail in TeacherAnswer on q.QuestionID equals tDetail.detail.QuestionID into tList
                        from tDetail in tList.DefaultIfEmpty()
                        join lDetail in LeaderAnswer on q.QuestionID equals lDetail.detail.QuestionID into lList
                        from lDetail in lList.DefaultIfEmpty()
                        select new {q,tList, lList });
    
    
    
    var resultSet = (from combo in combination
                    select new 
                    {
                        QuestionID = (combo.q.QuestionID == null ? 0 : combo.q.QuestionID),
                        IndicatorID = combo.q.ID,
                        QuestionDescription = combo.q.Description,
                        TeacherAnswerKey = (combo.tList.Select(x => x.detail.AnswerKey).FirstOrDefault() == null ? 0 : combo.tList.Select(y => y.detail.AnswerKey).FirstOrDefault()),
                        LeaderAnswerKey = (combo.lList.Select(x => x.detail.AnswerKey).FirstOrDefault() == null ? 0 : combo.lList.Select(y => y.detail.AnswerKey).FirstOrDefault()),
                        TeacherID = (combo.tList.Select(y => y.answer.TeacherID).FirstOrDefault() == null ? "" : combo.tList.Select(y => y.answer.TeacherID).FirstOrDefault()),
                        LeaderID = (combo.lList.Select(x => x.answer.LeaderID).FirstOrDefault() == null ? "" : combo.lList.Select(y => y.answer.LeaderID).FirstOrDefault()),
                        TeacherStatusKey = (combo.tList.Select(x => x.answer.StatusKey).FirstOrDefault() == null ? 0 : combo.tList.Select(y => y.answer.StatusKey).FirstOrDefault()),
                        LeaderStatusKey = (combo.lList.Select(x => x.answer.StatusKey).FirstOrDefault() == null ? 0 : combo.lList.Select(y => y.answer.StatusKey).FirstOrDefault()),
                        TeacherAnswerDetailKey = (combo.tList.Select(x => x.answer.TeacherDPSID).FirstOrDefault() == null ? 0 : combo.tList.Select(y => y.detail.AnswerDetailKey).FirstOrDefault()),
                        TeacherAnswerOptionKey = (combo.tList.Select(x => x.answer.TeacherDPSID).FirstOrDefault() == null ? 0 : combo.tList.Select(y => y.detail.AnswerOptionKey).FirstOrDefault()),
                        TeacherComment = combo.tList.Select(y => y.detail.Comment).FirstOrDefault(),
                        LeaderAnswerDetailKey = (combo.lList.Select(x => x.answer.LeaderID).FirstOrDefault() == null ? 0 : combo.lList.Select(y => y.detail.AnswerDetailKey).FirstOrDefault()),
                        LeaderAnswerOptionKey = (combo.lList.Select(x => x.answer.LeaderDPSID).FirstOrDefault() == null ? 0 : combo.lList.Select(y => y.detail.AnswerOptionKey).FirstOrDefault()),
                        LeaderComment = combo.lList.Select(y => y.detail.Comment).FirstOrDefault(),
                    }).ToList();
    

    【讨论】:

    • 您实际上并不需要所有这些括号(最后一个查询除外,因为调用了ToList):P
    • @ShlomiBorovitz - “括号”是什么意思?再次感谢您的帮助。
    • 这是最不重要的事情,但是,我的意思是所有这些 ( ) 围绕您的查询。这就是我添加“:P”的原因
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    • 1970-01-01
    • 2015-04-17
    相关资源
    最近更新 更多