Связывание нескольких таблиц в LINQ to SQL - PullRequest
2 голосов
/ 14 июля 2010

Хотелось бы получить список альбомов (Distinct), который пел ArtistId = 1

Я очень новичок в LINQ to SQL и не знаю, как объединить несколько таблиц. Пожалуйста, смотрите схему базы данных ниже: альтернативный текст http://a.imageshack.us/img155/8572/13690801.jpg

SingBy - это средняя таблица между Track и Artist.

Как мне этого добиться?

Ответы [ 6 ]

7 голосов
/ 14 июля 2010
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;

Я уверен, что должен быть лучший способ.Вы должны посмотреть на создание свойств навигации на ваших сущностей.Свойства навигации похожи на внешние ключи.

Правка - исправлено для получения альбомов, а не исполнителей.

2 голосов
/ 14 июля 2010

Теперь я написал коды, как показано ниже, и это работает.

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>;

Я тестировал версию Чада, и она тоже работает. Я хотел бы знать, какой путь лучше и хорош для оптимизации запросов? Спасибо всем.

1 голос
/ 14 июля 2010

Если у вас определены все отношения внешнего ключа, вы сможете выполнить вызов, как показано ниже:

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();
0 голосов
/ 14 июля 2010
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;
0 голосов
/ 14 июля 2010
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();

Эй, ТТКГ, выше самый простой способ сделать это.Это связано с тем, что выполнение Distinct над списком объектов не будет выполняться на основе идентификатора альбома.

Либо вы делаете это в два этапа, как описано выше, либо вы пишете свой собственный Album Comparer, который указывает уникальность на основеAlbumId и передайте его вызову Distinct в List.

ПРИМЕЧАНИЕ:

Вышеописанное будет работать только в том случае, если вы определили ограничения в вашем DBML, но лучше - в вашей БД.

Для передового опыта всегда определяйте свои отношения В БАЗЕ ДАННЫХ при использовании Linq к SQL, поскольку Linq к SQL не похож на EF или NHibernate, поскольку он не «абстрагирует» вашу базу данных, он просто отражает ее.Это инструмент для Data Driven Design, а не Domain Driven, поэтому определите отношения в БД.

0 голосов
/ 14 июля 2010

Хотелось бы получить список альбомов (Четко), который был спет 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...