LINQ to entities子查询Parent具有某些属性的子查询

时间:2012-04-27 10:49:35

标签: c# linq linq-to-entities

对实体使用C#和LINQ我遇到了子实体和父实体搜索的问题。在概念上,我试图得到一个IEnumerable孩子的集合,这些孩子具有某些属性,并且这些孩子的父母也有某些属性。

具体而言,我有路线和街道,它们有很多关系。我试图在特定路线上找到街道,其中街道具有LeftNote或RightNote的正面属性(LeftNote和RightNote是字符串,我正在搜索非空格的字符串)。

我有以下实体(为清晰起见而减少)

public class Route
{
    public int RouteID { get; set; }

    public virtual ICollection<Street> Streets { get; set; }
}

public class Street
{
    public string LeftNote { get; set; }

    public string RightNote { get; set; }

    public virtual ICollection<Route> Routes { get; set; }
}

我有以下LINQ表达式:

var streets = this.repository.Routes
                        .Where(r => r.RouteID == routeId).FirstOrDefault()
                        .Streets
                        .Where(s => s.LeftNote.Length > 0 || s.RightNote.Length > 0);

这非常有效,直到我针对Route存在的实体数据执行此操作,但没有具有LeftNotes或RightNotes的街道。在这些情况下,我得到一个NullReference异常。我试图找到一种方法来正确表达这个处理没有Streets与LeftNotes的查询(应该总是有一个匹配routeId的路由。如果不是这是一个有效的异常情况,应该抛出错误)。

编辑:问题似乎是在空字符串周围,而不是与LINQ构造相关的任何内容。

6 个答案:

答案 0 :(得分:1)

你的意思是

var streets = repository.Streets.Where
       (s => s.Routes.Any(r => r.RouteID == routeId )
             && (s.LeftNote.Length > 0 || s.RightNote.Length > 0));

答案 1 :(得分:1)

var streets = this.repository
                  .Routes
                  .Where(r => r.RouteID == routeId).FirstOrDefault()
                  .Streets
                  .Where(s => s.LeftNote !=null ? s.LeftNote.Length > 0 : false
                          || s.RightNote !=null ? s.RightNote.Length > 0 : false);

没有对它进行过测试,但认为它应该可行。

OR

this.repository.Streets(s=>(s.LeftNote.Length >0 || s.RightNote.Length > 0 ) 
                             && s.Routes.routeId==routeId));

答案 2 :(得分:1)

只需使用String.IsNullOrEmpty()。

var streets = this.repository
                .Routes
                .Where(r => r.RouteID == routeId).FirstOrDefault()
                .Streets
                .Where(s => !String.IsNullOrEmpty(s.LeftNote) ||
                            !String.IsNullOrEmpty(s.RightNote));

答案 3 :(得分:0)

请尝试以下方法:

var streets = this.repository.Routes
                             .Where(r => r.RouteID == routeId).FirstOrDefault()
                             .Streets
                             .Where(s => s.LeftNote ? s.LeftNote.Length > 0 : false || s.RightNote ? s.RightNote.Length > 0 : true);

<强>更新

var streets = this.repository.Streets
                             .Where(s => s.Routes.RouteID == routeId && s.LeftNote.Length > 0 || s.RightNote.Length > 0);

在插入新代码后更新代码。

首先使用false的原因是强制验证第二个或子句。不确定以下是否有效。

答案 4 :(得分:0)

是否必须在一个查询中执行

IEnumerable<Street> streets = Enumerable.Empty<Street>();
var route = this.repository
                .Routes
                .Where(r => r.RouteID == routeId).FirstOrDefault()

if(route != null && route.Streets.Any())
{
    streets = route.Streets
                   .Where(s => s.LeftNote.Length > 0 
                            || s.RightNote.Length > 0);
}

答案 5 :(得分:0)

尝试将LINQ表达式更改为此

var streets = this.repository.Routes
                  .Where(r => r.RouteID == routeId).FirstOrDefault()
                  .Where(r => r.Streets.Any(s => s.LeftNote.Length > 0 || s.RightNote.Length > 0));
相关问题