Подтвердить что ты не робот

Включить вложенные объекты, используя LINQ

Я впервые встречаюсь с LINQ, и сначала использую код EF 4.1.

У меня есть объекты, содержащие вложенные списки других объектов, например:

class Release
{
    int ReleaseID { get; set; }
    string Title { get; set; }
    ICollection<OriginalTrack> OriginalTracks { get; set; }
}

class OriginalTrack
{
    int OriginalTrackID { get; set; }
    string Title { get; set; }
    ICollection<Release> Releases { get; set; }
    ICollection<OriginalArtist> OriginalArtists { get; set; }
}

class OriginalArtist
{
    int OriginalArtistID { get; set; }
    string Name { get; set; }
    ICollection<OriginalTrack> OriginalTracks { get; set; }
}

Мне интересно, какой самый быстрый способ в одном запросе LINQ получить всю информацию о том, где ReleaseID == some value.

Я сделал домашнее задание, но нашел решения, требующие неявного восстановления объекта (обычно анонимного) с требуемыми данными. Я хочу, чтобы данные были из базы данных в точном формате, который хранится в базе данных, т.е. Вытягивая объект Release с соответствующими выводами ReleaseID и заполняет все данные OriginalTrack и OriginalArtist в списках.

Я знаю о Include(), но не уверен, как применить его для нескольких объектов.

Вся помощь очень ценится.

4b9b3361

Ответ 1

Не беспокойтесь об использовании здесь.

просто сделайте следующее:

var query = 
    from release in ctx.Releases
    select new {
        release,
        originalTracks = from track in release.OriginalTracks
                         select new {
                               track,
                               releases = track.Releases,
                               orignialArtist = from artist in track.OriginalArtists
                                                select new {
                                                     artist,
                                                     artist.OriginalTracks
                                                }
                         }
        }

var Releases = query.Select(x => x.Release);

Должен загружать все ваши данные

Я работал с информацией из этого сообщения здесь.

http://blogs.msdn.com/b/alexj/archive/2009/10/13/tip-37-how-to-do-a-conditional-include.aspx

Ответ 2

Используйте Include. Это цель Include, и нет причин писать кучу вложенных операторов select.

context.Releases.Include("OriginalTracks.OriginalArtist")
    .Where(release => release.ReleaseID == id);

Это проще писать, проще читать и сохраняет существующую структуру данных.

Чтобы использовать Include, вам нужно указать имя свойства, которое вы хотите вернуть, - это означает, что имя существует в коде, а не в базе данных. Например:

  • .Include("OriginalTracks") будет включать свойство OriginalTracks на каждом выпуске
  • .Include("OriginalTracks.OriginalArtist") будет включать свойство OriginalTracks для каждой версии Release и OriginalArtist на каждой дорожке (обратите внимание, что это невозможно - синтаксически или логически - включить OriginalArtist в том числе с OriginalTrack)
  • .Include("OriginalTracks").Include("OtherProperty") будет включать объекты OriginalTracks и OtherProperty в каждой версии.

Вы можете связать столько, сколько хотите, например:

.Include("Tracks.Artist").Include("AnotherProperty")
    .Include("ThirdProperty.SomeItems").Where(r => r.something);

отлично. Единственное требование состоит в том, что вы помещаете Include в EntitySet, а не в запрос - вы не можете .Where().Include().

Ответ 3

Чтобы включить вложенные объекты без использования строковых литералов, используйте Select, например:

context.Releases.Include(r => r.OriginalTracks.Select(t => t.OriginalArtist))
    .Where(release => release.ReleaseID == id);