【问题标题】:Linq Query using navigation properties and Where clause使用导航属性和 Where 子句的 Linq 查询
【发布时间】:2018-01-29 16:12:18
【问题描述】:

我正在尝试使用导航属性编写 linq 查询。我正在从 3 个实体中选择属性:

  • 储物柜
  • 节列
  • 合同

我需要 Lockers 表中满足以下所有条件的所有行:LockerTypeId = "308", .OutOfOrder != true, x.SectionColumn.SectionId == "52")。

下面没有条件 x.SectionColumn.SectionId == "52" 的查询可以正常工作,并准确返回我需要的内容,除了我所期望的返回任何值的 Section id 的行。

    from l in Lockers.Where(x => x.LockerTypeId == "308" && x.OutOfOrder != 
    true).DefaultIfEmpty()
               select new 
                {
                   ColumnNumber = l.ColumnNumber,
                   LockerTypeId = l.LockerTypeId,
                   OutOfOrder = l.OutOfOrder,
                   Rented = l.Contracts.Select(x => x.Contract_ID < 0 ?                   
                     false : true).FirstOrDefault(),
                   Section = l.SectionColumn.SectionId
                   }

当我如下添加条件 'x.SectionColumn.SectionId == "52"' 时,我收到错误“转换为值类型 'System.Int32' 失败,因为具体化值为 null”。结果类型的泛型参数或查询必须在 linqpad 中使用可空类型”。SectionId 是字符串(SQL Server 中的 varchar)。

    from l in Lockers.Where(x => x.LockerTypeId == "308" && x.OutOfOrder != 
    true).DefaultIfEmpty()

如果能帮助我正确编写此查询,我将不胜感激。

【问题讨论】:

  • 请编辑第二个代码示例。那里没有SectionId 。
  • Section = l.SectionColumn != null?l.SectionColumn.SectionId?0:0
  • 如果 SectionColumn 在表架构中允许为空?
  • 在访问 l.SectionColumn.SectionId 之前,您必须检查 l.SectionColumn is not equal null

标签: c# entity-framework linq lambda linq-to-entities


【解决方案1】:

首先,如果您坚持使用纯 LINQ,您的代码可能会更直接一些。在这种情况下,您的代码应如下所示。

 var results = from l in Lockers
               where l.LockerTypeId == "308" && l.OutOfOrder != true && l.SectionColumn.SectionId == "52"
               select new 
               {
                    ColumnNumber = l.ColumnNumber,
                    LockerTypeId = l.LockerTypeId,
                    OutOfOrder = l.OutOfOrder,
                    Rented = l.Contracts.Select(x => x.Contract_ID < 0 ? false : true).FirstOrDefault(),
                    Section = l.SectionColumn.SectionId
               }

如果l.SectionColumn.SectionId 代表有效的导航属性并且是string 类型,那么这应该可以正常工作。

您确实没有对问题进行彻底的描述(而且您似乎没有坚持解决现场问题),但如果 l.SectionColumn 可以为空,您应该能够将您的代码更新为像这样。

 var results = from l in Lockers
               let sectionId = (l.SectionColumn != null) ? l.SectionColumn.SectionId : null
               where l.LockerTypeId == "308" && l.OutOfOrder != true && sectionId == "52"
               select new 
               {
                    ColumnNumber = l.ColumnNumber,
                    LockerTypeId = l.LockerTypeId,
                    OutOfOrder = l.OutOfOrder,
                    Rented = l.Contracts.Select(x => x.Contract_ID < 0 ? false : true).FirstOrDefault(),
                    Section = l.SectionColumn.SectionId
               }

【讨论】:

  • 只要有的SectionColumn为空值,这个方案就不能成立
  • 在访问 l.SectionColumn.SectionId 之前,您必须检查 l.SectionColumn is not equal null
  • 谢谢 - 我会试试看的。
  • @محمدالنعيمي:我更新了我的答案以包含这种可能性。
  • 按照建议使用标准 linq 语法 - 查询现在在 linqpad 中工作。不知道为什么 lambda 版本不起作用。感谢您的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-08
  • 1970-01-01
  • 2018-08-14
  • 1970-01-01
  • 2021-03-08
  • 2020-12-31
相关资源
最近更新 更多