Linq左外连接不起作用

时间:2013-02-19 19:09:08

标签: asp.net-mvc asp.net-mvc-3 linq entity-framework-4

使用MSDN文章"How to: Perform Left Outer Joins (C# Programming Guide)"中的技术,我试图在Linq代码中创建一个左外连接。文章提到使用DefaultIfEmpty方法从组连接创建左外连接。基本上,它指示程序包括左(第一)集合的结果,即使在正确的集合中没有结果。

此程序执行的方式是,它就像没有指定外部联接一样。

在我们的数据库中,AgentProductTraining是我们的代理人所采用的课程集合。通常,如果没有在Course表中输入相应的值,则无法在其适当的表格中输入CourseMaterials。但是,偶尔会出现这种情况,因此我们希望确保即使在Course中列出AgentProductTrainingCourseMaterials中没有任何相应信息,也会返回结果。

        var training = from a in db.AgentProductTraining
                       join m in db.CourseMaterials on a.CourseCode equals m.CourseCode into apm
                       where
                           a.SymNumber == id 
                           from m in apm.DefaultIfEmpty()
                           where m.EffectiveDate <= a.DateTaken
                           && ((m.TerminationDate > a.DateTaken) | (m.TerminationDate == null))
                       select new
                                  {
                                      a.AgentProdTrainId,
                                      a.CourseCode,
                                      a.Course.CourseDescription,
                                      a.Course.Partner,
                                      a.DateTaken,
                                      a.DateExpired,
                                      a.LastChangeOperator,
                                      a.LastChangeDate,
                                      a.ProductCode,
                                      a.Product.ProductDescription,
                                      m.MaterialId,
                                      m.Description,
                                      a.Method
                                  };

1 个答案:

答案 0 :(得分:3)

MSDN示例使用新变量subpet

var query = from person in people
                    join pet in pets on person equals pet.Owner into gj
                    from subpet in gj.DefaultIfEmpty()
                    select new { person.FirstName, PetName = (subpet == null ? String.Empty : subpet.Name) };

所以你必须使用自己的“subpet”,我使用submat变量重写了你的代码:

        var training = from a in db.AgentProductTraining
                       join m in db.CourseMaterials on a.CourseCode equals m.CourseCode into apm
                       where
                           a.SymNumber == id
                           from submat in apm.DefaultIfEmpty()
                           where 
                           (submat.EffectiveDate <= a.DateTaken || submat.EffectiveDate == null) &&
                           (submat.TerminationDate > a.DateTaken || submat.TerminationDate == null)
                       select new
                                  {
                                      a.AgentProdTrainId,
                                      a.CourseCode,
                                      a.Course.CourseDescription,
                                      a.Course.Partner,
                                      a.DateTaken,
                                      a.DateExpired,
                                      a.LastChangeOperator,
                                      a.LastChangeDate,
                                      a.ProductCode,
                                      a.Product.ProductDescription,
                                      MaterialId = (submat==null?-1:submat.MaterialId),
                                      Description = (submat==null?String.Empty:submat.Description),
                                      a.Method
                                  };