将LINQ中的多个表链接到SQL

时间:2010-07-14 00:00:17

标签: c# linq linq-to-sql join

我想获得由artistId = 1

演唱的专辑(Distinct)列表

我是LINQ to SQL的新手,不知道如何连接多个表。请参阅下面的数据库图表: alt text http://a.imageshack.us/img155/8572/13690801.jpg

SingBy是Track和Artist之间的中间表。

我怎么能实现这个目标?

6 个答案:

答案 0 :(得分:7)

var albums = from singer in artist
      from sb in singby
      from t in track
      from a in album
    where singer.artistId == 1 && 
      sb.artistId == 1 && 
      sb.trackId == t.trackId && 
      a.albumId == track.albumId
    select a;

我确信必须有更好的方法。您应该考虑在实体上创建导航属性。导航属性就像外键一样。

编辑 - 更正以获取相册,而不是艺术家。

答案 1 :(得分:2)

现在,我编写了如下代码,它可以工作。

var albums = (from a in db.artists
                          where a.artistId == 1
                          join sb in db.singbies on a equals sb.artist
                          join t in db.tracks on sb.track equals t
                          join al in db.albums on t.album equals al
                          select al).Distinct();

return albums.ToList() as List<album>;

我测试了Chad的版本,它也有效。我想知道哪种方式更好,更适合查询优化?谢谢大家。

答案 2 :(得分:1)

如果您已定义了所有外键关系,则应该能够发出如下呼叫:

dc.GetTable<Album>().Where(a => a.Track.Singby.ArtistId == 1).ToList();

这依赖于Linq在需要时自动为Track和Singby执行延迟加载。显然,当数据库中有大量数据并且性能至关重要时,这不是最佳选择。您可以使用GroupBy或Distinct操作链接查询,以仅返回不同的集合,例如

dc.GetTable<Album>().Where(a => a.Track.Singby.ArtistId == 1).Distinct().ToList();

答案 3 :(得分:0)

  

我想获取相册列表   (区别)由歌唱   artistId = 1

DBDataContext = new DBDataContext();
album[] = db.artists.Where(a => a.artistId == 1) /* Your artist */
  .SelectMany(a => a.singbies) /* Check if `singby` converted to `singbies` */
  .Select(sb => sb.track) /* The tracks */
  .Select(t => t.album) /* The albums */
  .GroupBy(al => al.albumId) /* Group by id */ /* "Distinct" for objects */
  .Select(alG => alG.First()) /* Select first of each group */
  .ToArray();

答案 4 :(得分:0)

IEnumerable<Album> query =
  from album in myDC.Albums
  let artists = 
    from track in album.Tracks
    from singBy in track.SingBys
    select singBy.Artist
  where artists.Any(artist => artist.ArtistId == 1)
  select album;

答案 5 :(得分:-2)

List<int> Ids = dc.Albums.Where(a => a.Track.Singby.ArtistId == 1).Select(a=> a.albumId).Distinct().ToList();
List<Album> distinctAlbums = dc.Albums.Where(a => distinctAlbumIds.Contains(a.albumId)).ToList();

嘿TTCG,上面是最简单的方法。这是因为在对象列表上做一个区别不会基于albumId。

您可以按上述两个步骤执行此操作,或者编写自己的Album Comparer,根据AlbumId指定唯一性,并将其传递给List上的Distinct调用。

注意:

只有在DBML中定义了约束时,上述操作才有效,但更好的是在数据库中。

对于最佳实践,在使用Linq to SQL时始终定义您在数据库中的关系,因为Linq to SQL不像EF或NHibernate,因为它不会“抽象”您的数据库,它只是反映它。它是数据驱动设计的工具,而不是域驱动的工具,因此在db中定义关系。