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?


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

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

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

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();
}

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.