Включить вложенные объекты, используя 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()
, но не уверен, как применить его для нескольких объектов.
Вся помощь очень ценится.
Ответы
Ответ 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);