Linq Query使用导航属性和Where子句

时间:2018-01-29 16:12:19

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

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

  • 储物柜
  • SectionColumn
  • 合同

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

下面的查询没有条件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
                   }

当我添加条件&#39; x.SectionColumn.SectionId ==&#34; 52&#34;&#39;如下所示我得到错误&#34;转换为值类型&#39; System.Int32&#39;失败,因为物化值为空&#34;。结果类型的通用参数或查询必须使用可空类型&#34;在linqpad。 SectionId是一个字符串(SQL Server中的varchar)。

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

我将非常感谢您正确撰写此查询的帮助。

1 个答案:

答案 0 :(得分: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
               }