Saya mencoba untuk mengisi GridView
menggunakan Entity Frameworkm tetapi setiap kali saya mendapatkan kesalahan berikut:
"Pengakses properti 'LoanProduct' pada objek 'COSIS_DAL.MemberLoan' memberikan pengecualian berikut: Contoh ObjectContext telah dibuang dan tidak dapat lagi digunakan untuk operasi yang memerlukan sambungan."
Kode saya adalah:
public List<MemberLoan> GetAllMembersForLoan(string keyword)
{
using (CosisEntities db = new CosisEntities())
{
IQueryable<MemberLoan> query = db.MemberLoans.OrderByDescending(m => m.LoanDate);
if (!string.IsNullOrEmpty(keyword))
{
keyword = keyword.ToLower();
query = query.Where(m =>
m.LoanProviderCode.Contains(keyword)
|| m.MemNo.Contains(keyword)
|| (!string.IsNullOrEmpty(m.LoanProduct.LoanProductName) && m.LoanProduct.LoanProductName.ToLower().Contains(keyword))
|| m.Membership.MemName.Contains(keyword)
|| m.GeneralMasterInformation.Description.Contains(keyword)
);
}
return query.ToList();
}
}
protected void btnSearch_Click(object sender, ImageClickEventArgs e)
{
string keyword = txtKeyword.Text.ToLower();
LoanController c = new LoanController();
List<COSIS_DAL.MemberLoan> list = new List<COSIS_DAL.MemberLoan>();
list = c.GetAllMembersForLoan(keyword);
if (list.Count <= 0)
{
lblMsg.Text = "No Records Found";
GridView1.DataSourceID = null;
GridView1.DataSource = null;
GridView1.DataBind();
}
else
{
lblMsg.Text = "";
GridView1.DataSourceID = null;
GridView1.DataSource = list;
GridView1.DataBind();
}
}
Kesalahan menyebutkan LoanProductName
kolom dari Gridview
. Disebutkan: Saya menggunakan C #, ASP.net, SQL-Server 2008 sebagai DB back end.
Saya cukup baru di Entity Framework. Saya tidak mengerti mengapa saya mendapatkan kesalahan ini. Adakah yang bisa membantu saya?
c#
asp.net
entity-framework
Barsan
sumber
sumber
query.Include("SomeOtherTable")
db.MemberLoans.Include("LoanProduct").OrderByDescending()
periksa sintaksnya karena saya tidak memiliki VS di depan saya.db.MemberLoans.Include("LoanProduct").Include("SomeOtherTable)
. Periksa jawaban oleh @Tragedian dan @lazyberezovskyJawaban:
Secara default, Entity Framework menggunakan pemuatan lambat untuk properti navigasi. Itulah mengapa properti ini harus ditandai sebagai virtual - EF membuat kelas proxy untuk entitas Anda dan mengganti properti navigasi untuk memungkinkan pemuatan lambat. Misalnya jika Anda memiliki entitas ini:
Kerangka Kerja Entitas akan mengembalikan proxy yang diwarisi dari entitas ini dan memberikan instance DbContext ke proxy ini untuk memungkinkan pemuatan keanggotaan yang lambat nanti:
Jadi, entitas memiliki turunan DbContext yang digunakan untuk memuat entitas. Itu masalahmu. Anda telah
using
memblokir penggunaan CosisEntities. Yang membuang konteks sebelum entitas dikembalikan. Ketika beberapa kode kemudian mencoba menggunakan properti navigasi yang dimuat lambat, gagal, karena konteks dibuang pada saat itu.Untuk memperbaiki perilaku ini, Anda dapat menggunakan eager loading dari properti navigasi yang Anda perlukan nanti:
Itu akan memuat semua keanggotaan dan pemuatan lambat tidak akan digunakan. Untuk detailnya lihat Memuat artikel Entitas Terkait di MSDN.
sumber
db.MemberLoans.Include(m => m.Membership).Include(m => m.LoanProduct).OrderByDescending(m => m.LoanDate);
yang akan menghasilkan kueri JOIN dan mengembalikan semua data sekaligus.The
CosisEntities
kelas AndaDbContext
. Saat Anda membuat konteks dalamusing
blok, Anda menentukan batas untuk operasi berorientasi data Anda.Di kode Anda, Anda mencoba mengeluarkan hasil kueri dari suatu metode dan kemudian mengakhiri konteks di dalam metode tersebut. Operasi yang Anda berikan hasilnya untuk kemudian mencoba mengakses entitas untuk mengisi tampilan kisi. Di suatu tempat dalam proses pengikatan ke kisi, properti yang dimuat lambat sedang diakses dan Entity Framework mencoba melakukan pencarian untuk mendapatkan nilai. Gagal, karena konteks terkait telah berakhir.
Anda memiliki dua masalah:
Anda malas memuat entitas saat mengikat ke kisi. Ini berarti Anda melakukan banyak operasi kueri terpisah ke SQL Server, yang akan memperlambat semuanya. Anda dapat memperbaiki masalah ini dengan membuat properti terkait eager-loaded secara default, atau meminta Entity Framework untuk menyertakannya dalam hasil kueri ini dengan menggunakan
Include
metode ekstensi.Anda mengakhiri konteks Anda sebelum waktunya: a
DbContext
harus tersedia di seluruh unit pekerjaan yang sedang dilakukan, hanya membuangnya saat Anda selesai dengan pekerjaan yang ada. Dalam kasus ASP.NET, unit kerja biasanya menangani permintaan HTTP.sumber
Intinya
Kode Anda telah mengambil data (entitas) melalui kerangka-entitas dengan pemuatan lambat diaktifkan dan setelah DbContext dibuang, kode Anda mereferensikan properti (entitas terkait / hubungan / navigasi) yang tidak diminta secara eksplisit.
Lebih spesifik
Dengan
InvalidOperationException
pesan ini selalu berarti hal yang sama: Anda meminta data (entitas) dari kerangka-entitas setelah DbContext telah dibuang.Kasus sederhana:
(kelas-kelas ini akan digunakan untuk semua contoh dalam jawaban ini, dan menganggap semua properti navigasi telah dikonfigurasi dengan benar dan memiliki tabel terkait dalam database)
Baris terakhir akan menampilkan
InvalidOperationException
karena dbContext belum menonaktifkan pemuatan lambat dan kode mengakses properti navigasi Pet setelah Context dibuang oleh pernyataan using.Debugging
Bagaimana Anda menemukan sumber pengecualian ini? Selain melihat pengecualian itu sendiri, yang akan dilemparkan tepat di lokasi di mana itu terjadi, aturan umum debugging di Visual Studio berlaku: tempatkan breakpoint strategis dan periksa variabel Anda , baik dengan mengarahkan mouse ke atas namanya, membuka ( Cepat) Jendela Tonton atau menggunakan berbagai panel debugging seperti Lokal dan Mobil.
Jika Anda ingin mengetahui di mana referensi ditetapkan atau tidak, klik kanan namanya dan pilih "Temukan Semua Referensi". Anda kemudian dapat menempatkan breakpoint di setiap lokasi yang meminta data, dan menjalankan program Anda dengan debugger terpasang. Setiap kali debugger berhenti pada breakpoint seperti itu, Anda perlu menentukan apakah properti navigasi Anda seharusnya sudah terisi atau jika data yang diminta diperlukan.
Cara untuk Menghindari
Nonaktifkan Pemuatan Lambat
Pro: Alih-alih melempar InvalidOperationException, properti akan menjadi null. Mengakses properti null atau mencoba mengubah properti properti ini akan memunculkan NullReferenceException .
Cara meminta objek secara eksplisit saat diperlukan:
Pada contoh sebelumnya, Entity Framework akan mewujudkan Pet selain Person. Ini bisa menguntungkan karena ini adalah panggilan tunggal database. (Namun, bisa juga ada masalah performa yang sangat besar tergantung pada jumlah hasil yang dikembalikan dan jumlah properti navigasi yang diminta, dalam hal ini, tidak akan ada penalti performa karena kedua instance hanya satu record dan satu gabungan).
atau
Pada contoh sebelumnya, Entity Framework akan mewujudkan Pet secara independen dari Orang dengan melakukan panggilan tambahan ke database. Secara default, Entity Framework melacak objek yang telah diambil dari database dan jika menemukan properti navigasi yang cocok, maka secara otomatis akan mengisi entitas ini. Dalam hal ini karena
PetId
padaPerson
objek sesuai denganPet.Id
, Entity Framework akan menetapkanPerson.Pet
kePet
nilai diambil, sebelum nilai ditugaskan untuk variabel hewan peliharaan.Saya selalu merekomendasikan pendekatan ini karena memaksa pemrogram untuk memahami kapan dan bagaimana kode meminta data melalui Entity Framework. Ketika kode melontarkan pengecualian referensi null pada properti entitas, Anda hampir selalu dapat memastikan bahwa Anda tidak secara eksplisit meminta data tersebut.
sumber
Ini jawaban yang sangat terlambat tetapi saya menyelesaikan masalah mematikan pemuatan lambat:
sumber
Dalam kasus saya, saya melewatkan semua model 'Users' ke kolom dan itu tidak dipetakan dengan benar, jadi saya hanya meneruskan 'Users.Name' dan itu memperbaikinya.
sumber
Sebagian besar jawaban lain mengarah ke eager loading, tetapi saya menemukan solusi lain.
Dalam kasus saya, saya memiliki objek EF
InventoryItem
dengan koleksiInvActivity
objek anak.Dan karena saya menarik dari kumpulan objek anak alih-alih kueri konteks (dengan
IQueryable
),Include()
fungsi itu tidak tersedia untuk mengimplementasikan eager loading. Jadi, solusi saya adalah membuat konteks dari tempat saya menggunakanGetLatestActivity()
danattach()
objek yang dikembalikan:Dengan demikian Anda tidak terjebak dengan eager loading.
sumber
Jika Anda menggunakan ASP.NET Core dan bertanya-tanya mengapa Anda mendapatkan pesan ini di salah satu metode pengontrol async Anda, pastikan Anda mengembalikan
Task
daripadavoid
- ASP.NET Core membuang konteks yang diinjeksi.(Saya memposting jawaban ini karena pertanyaan ini berada di urutan teratas dalam hasil pencarian untuk pesan pengecualian itu dan ini adalah masalah yang halus - mungkin berguna bagi orang yang Google untuk itu.)
sumber