EF和LINQ通过子集属性查询

时间:2013-08-14 03:13:20

标签: c# linq entity-framework

我正在尝试根据子集合的子集合中的值来排序“父”项目列表。这是具体的......

我有一个Film实体(映射到Films表),它有一对多的Release实体集合(映射到Releases表)。每个版本都有一个或多个ReleaseDate实体(映射到ReleaseDates表)。

public class Film {
    public int Id {get;set;}
    public string Title {get;set;}
    /* ... more properties here ...*/
}

public class Release {
    public int Id {get;set;}
    public int FilmId {get;set;}
    public virtual Film Film {get;set;}
    public virtual ICollection<ReleaseDate> ReleaseDates { get; set; }
    /* ... more properties here ...*/
}

public class ReleaseDate {
    public int Id {get;set;}
    public DateTime Date {get;set;}
    public int ReleaseId {get;set;}
    public virtual Release Release {get;set;}
    /* ... more properties here ...*/
}

现在,我想在最早的发布日期订购电影,但显然电影可能没有发行版,发行版可能没有发行日期(再次,1- *关系)。 SQL等价物将是......

SELECT * /* or whatever columns...*/
FROM dbo.Films F
LEFT OUTER JOIN dbo.Releases R ON R.FilmId = F.Id
LEFT OUTER JOIN dbo.ReleaseDates RD ON RD.ReleaseId = R.Id
ORDER BY RD.[Date] ASC /* or DESC */

我该怎么做呢?

2 个答案:

答案 0 :(得分:0)

var orderedFilms = Films.OrderBy(a=> a.Releases.Any() ?  
                                     a.Releases.Select(x=>x.ReleaseDates.Any() ?
                                                           x.ReleaseDates.Min(d=>d.Date).Date :
                                                             DateTime.Now).Min() : DateTime.Now);

答案 1 :(得分:0)

好吧,我改变了我对这个问题的处理方法,并根据那里的“正常”方法解决了这个问题,其中一个作为答案给出,但后来被海报删除了。我最终做的是将我的选择向下移动到存储库层,在那里我有DbContext,并且能够像这样做一个“简单”的左外连接样式查询......

var films = (from f in db.Films
             join r in db.Releases on f.Id equals r.FilmId into FR
             from a in FR.DefaultIfEmpty()
             join d in db.ReleaseDates on a.Id equals d.ReleaseId into RRD
             from b in RRD.DefaultIfEmpty()
             orderby b.Date ascending
             select f);

@KingKing,感谢您的回答,我认为它可能在其他一些地方派上用场,我们根据子集合的属性甚至子子集合的属性来获得这些聚合字段。