Bagaimana cara menyertakan objek anak objek anak dalam Entity Framework 5

144

Saya menggunakan Entity Framework 5 code firstdan ASP.NET MVC 3.

Saya berjuang untuk mendapatkan objek anak dari objek anak untuk diisi. Di bawah ini adalah kelasku ..

Kelas aplikasi;

public class Application
{
     // Partial list of properties

     public virtual ICollection<Child> Children { get; set; }
}

Kelas anak:

public class Child
{
     // Partial list of properties

     public int ChildRelationshipTypeId { get; set; }

     public virtual ChildRelationshipType ChildRelationshipType { get; set; }
}

Kelas ChildRelationshipType:

public class ChildRelationshipType
{
     public int Id { get; set; }

     public string Name { get; set; }
}

Bagian dari metode GetAll di repositori untuk mengembalikan semua aplikasi:

return DatabaseContext.Applications
     .Include("Children");

Kelas Anak berisi referensi ke kelas ChildRelationshipType. Untuk bekerja dengan anak-anak aplikasi, saya akan memiliki sesuatu seperti ini:

foreach (Child child in application.Children)
{
     string childName = child.ChildRelationshipType.Name;
}

Saya mendapatkan kesalahan di sini bahwa konteks objek sudah ditutup.

Bagaimana cara menentukan bahwa setiap objek anak harus menyertakan ChildRelationshipTypeobjek seperti yang saya lakukan di atas?

Brendan Vogt
sumber
Kemungkinan duplikat dari Entity Framework - Sertakan Beberapa Tingkat Properti
Michael Freidgeim

Jawaban:

263

Jika Anda menyertakan pustaka, System.Data.EntityAnda bisa menggunakan metode overload Include()yang mengambil ekspresi lambda alih-alih string. Anda kemudian dapat mengganti Select()anak dengan ekspresi Linq daripada stringjalur.

return DatabaseContext.Applications
     .Include(a => a.Children.Select(c => c.ChildRelationshipType));
Ryan Amies
sumber
6
Seperti yang dikatakan GraemeMiller, kelas yang diketik dengan kuat lebih baik untuk pemeliharaan daripada menggunakan string
Ryan Amies
Versi manakah metode lamba tersedia? Saya terjebak pada Basis Kode EF 4.0 .. dan tidak dapat membuat lamda berfungsi. Terima kasih atas masukannya.
granadaCoder
5
Ini akan berfungsi di EF 4, pastikan untuk menambahkan referensi keSystem.Data.Entity;
Ryan Amies
5
FYI - Di EF 6 namespace adalahMicrosoft.Data.Entity
Brad
1
Menggunakan EF 5, saya tidak bisa mendapatkan .Select (x => x.Child) tetapi ini berhasil - Entities.UserProfile storedProfile = db.UserProfiles .Include (s => s.ShippingAddress) .Include (st => st.ShippingAddress. StateProvince) .Include (b => b.BillingAddress) .Include (bs => bs.BillingAddress.StateProvince) .FirstOrDefault (x => x.UserId == userId);
Geovani Martinez
102

Dengan EF Core di .NET Core Anda dapat menggunakan kata kunci ThenInclude:

return DatabaseContext.Applications
 .Include(a => a.Children).ThenInclude(c => c.ChildRelationshipType);

Sertakan anak-anak dari koleksi anak-anak:

return DatabaseContext.Applications
 .Include(a => a.Childrens).ThenInclude(cs => cs.ChildRelationshipType1)
 .Include(a => a.Childrens).ThenInclude(cs => cs.ChildRelationshipType2);
Hayha
sumber
8
Terima kasih!!! Sangat membantu! Terkadang Anda mungkin mendapatkan kecerdasan yang salah, abaikan saja dan bangun! :)
muhihsan
Bagus, saya mencari .net core :)
Andy Clarke
1
Dan bagaimana jika Anak-anak adalah koleksi dan saya perlu menyertakan properti di bawahnya?
dodbrian
Menemukan kelebihan untuk itu. Awalnya tidak jelas.
dodbrian
2
@dodbrian Apa kelebihannya? Saya mencoba untuk membuat sarang .ThenInclude, di mana anak tersebut adalah sebuah koleksi.
Greg Hardin
23

Saya akhirnya melakukan hal berikut dan berhasil:

return DatabaseContext.Applications
     .Include("Children.ChildRelationshipType");
Brendan Vogt
sumber
78
Cara yang diketik dengan kuat lebih baik. String ajaib tidak bagus untuk refactoring
GraemeMiller
2

Contoh yang baik dalam menggunakan pola Repositori Generik dan mengimplementasikan solusi umum untuk ini mungkin terlihat seperti ini.

public IList<TEntity> Get<TParamater>(IList<Expression<Func<TEntity, TParamater>>> includeProperties)

{

    foreach (var include in includeProperties)
     {

        query = query.Include(include);
     }

        return query.ToList();
}
gcoleman0828
sumber
Bagaimana saya menyebut metode di atas? dapatkah Anda memberikan contoh
Jamee
@Jamee -List <Expression <Func <PersonObject, object >>> includers = new List <Expression <Func <PersonObject, object >>> (); Includers.Add (x => x.FirstName); Dapatkan <PersonObject> (termasuk);
gcoleman0828
1
Dan kueri berasal dari ...?
Doug Beard
Maaf @DougBeard, tidak mengikuti pertanyaan Anda.
gcoleman0828
1
@ gcoleman0828 Variabel kueri dalam cuplikan kode Anda di atas. Apakah itu dibuat secara ajaib? Dari mana asalnya
Doug Beard