【问题标题】:Optional condition in join clause - Linq连接子句中的可选条件 - Linq
【发布时间】:2018-11-22 10:09:44
【问题描述】:

我有以下 linq 查询

 var resultGuardian = from s in _db.Students
     join sg in _db.StudentGuardians on s.StudentID equals sg.StudentID
     join g in _db.Guardians on sg.GuardianId equals g.GuardianId
     join lr in _db.luRelationTypes on sg.RelationTypeID equals lr.RelationTypeID
     join ga in _db.GuardianAddresses on g.GuardianId equals ga.GuardianId
     join ad in _db.Addresses on ga.AddressID equals ad.AddressID
     join lt in _db.luAddressTypes on ad.AddressTypeID equals lt.AddressTypeID
     join lg in _db.luGenders on g.GenderID equals (int?)lg.GenderID into ssts
     from gdnr in ssts.DefaultIfEmpty()
     where
         s.TenantID == tenantid && sg.TenantID == tenantid && g.TenantID == tenantid &&
         s.StatusId == (int?)Extension.StatusType.Active //1
         && g.StatusID == (int?)Extension.StatusType.Active &&
         lr.StatusID == (int?)Extension.StatusType.Active && lr.TenantID == tenantid &&
         s.StudentID == sid
     select new
     {
         g.FirstName,
         g.LastName,
         IsPrimary = sg.IsPrimaryGuardian,
         g.Education,
         g.Email,
         g.Phone,
         lr.RelationCD,
         ga.IsStudentAddress,
         gdnr.GenderCD,
         lt.AddressName,
         ad.Address1,
         ad.Address2,
         ad.City,
         ad.State,
         ad.Zipcode

     };

上面的查询当ad.AddressTypeID是null时,没有返回任何结果。

如果ad.AddressTypeID 是null,我有要求,而不是从LuAddressTypes 获取AddressTypeCd=1 的默认记录。如果我尝试这种方式

join lt in LuAddressTypes on ad.AddressTypeID equals lt.AddressTypeID into v1
from v2 in v1.DefaultIfEmpty()
select new
     {      
         v2.AddressName,
         g.Phone,..

     });

结果v2.AddressName总是返回null。我也无法指定 AddressTypeCd=1 where 条件。 AddressTypeCd=1 不是 ad.AddressTypeID。

我需要v2.AddressName,其中AddressTypeCd=1。我怎样才能做到这一点? 查找相关实体all related entities

【问题讨论】:

  • 搜索 linq 左外连接。
  • LEFT OUTER JOIN in LINQ的可能重复
  • @AccessDenied - 感谢您的建议。
  • 请贴出涉及的实体类。还修复了示例查询 - 目前它正在使用一些不存在的别名 - ga、g、lr。
  • @IvanStoev - 当然可以。

标签: c# .net linq linq-to-entities


【解决方案1】:

您不能使用标准 LINQ join,但在 LINQ to Entities 中,您可以使用基于相关 Where 的替代连接语法 - EF 足够聪明,可以将其转换为 JOIN。

在你的情况下,而不是

join lt in _db.luAddressTypes on ad.AddressTypeID equals lt.AddressTypeID

你可以使用

from lt in _db.luAddressTypes.Where(lt => ad.AddressTypeID == lt.AddressTypeID
    || (ad.AddressTypeID == null && lt.AddressTypeCd == 1))

翻译成这样的

INNER JOIN [dbo].[LuAddressTypes] AS [Extent3]
    ON ([Extent2].[AddressTypeID] = [Extent3].[AddressTypeID])
        OR (([Extent2].[AddressTypeID] IS NULL) AND (1 = [Extent3].[AddressTypeCd]))

如果你想要LEFT OUTER JOIN,只需在上面一行的末尾添加.DefaultIfEmpty()。

【讨论】:

  • 感谢您的回答。它正在返回多条记录。你能建议我如何避免这种情况吗?
  • 添加.Take(1) :) 会把JOIN改成CROSS APPLY,但是效果应该是一样的。
猜你喜欢
  • 1970-01-01
  • 2016-01-12
  • 2020-06-12
  • 1970-01-01
  • 1970-01-01
  • 2012-07-08
  • 1970-01-01
  • 1970-01-01
  • 2010-11-29
相关资源
最近更新 更多