2

使用 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 异常。我正在尝试找到一种方法来正确表达此查询,该查询使用 LeftNotes 处理 Streets 的缺失(应该始终有一个与 routeId 匹配的 Route。如果不是,这是一个有效的异常情况,应该抛出和错误)。

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

4

6 回答 6

1

你真的是说

var streets = repository.Streets.Where
       (s => s.Routes.Any(r => r.RouteID == routeId )
             && (s.LeftNote.Length > 0 || s.RightNote.Length > 0));
于 2012-04-27T11:06:48.273 回答
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);

没有测试过,但认为它应该可以工作。

或者

this.repository.Streets(s=>(s.LeftNote.Length >0 || s.RightNote.Length > 0 ) 
                             && s.Routes.routeId==routeId));
于 2012-04-27T11:12:47.477 回答
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));
于 2012-04-27T11:25:29.413 回答
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 first 的原因是强制验证 second or 子句。不确定以下是否有效。

于 2012-04-27T10:57:10.933 回答
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);
}
于 2012-04-27T11:18:08.373 回答
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));
于 2012-04-27T11:29:05.750 回答