我想获得由artistId = 1
演唱的专辑(Distinct)列表我是LINQ to SQL的新手,不知道如何连接多个表。请参阅下面的数据库图表: alt text http://a.imageshack.us/img155/8572/13690801.jpg
SingBy是Track和Artist之间的中间表。
我怎么能实现这个目标?
答案 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中定义关系。