Sambungan LINQ menggunakan IEnumerable
koleksi berterusan
Apabila menggunakan klausa LINQ JOIN dalam pernyataan SELECT bagi pernyataan JOIN yang lain, ralat "Tidak boleh mencipta nilai tetap jenis API.Models.PersonProtocol. Hanya jenis primitif atau terhitung disokong dalam konteks ini" berlaku. Ralat ini berlaku kerana IEnumerable
KoleksippCombined
tidak boleh digunakan sebagai nilai malar dalam konteks pangkalan data.
Dalam kod yang disediakan:
<code class="language-csharp">var persons = db.Favorites .Where(x => x.userId == userId) .Join(db.Person, x => x.personId, y => y.personId, (x, y) => new PersonDTO { personId = y.personId, addressId = y.addressId, favoriteId = x.favoriteId, personProtocol = (ICollection<PersonProtocol>) ppCombined .Where(a => a.personId == x.personId) .Select( b => new PersonProtocol() { personProtocolId = b.personProtocolId, activateDt = b.activateDt, personId = b.personId }) });</code>
Kod ini cuba menggabungkan data daripada jadual db.Favorites
dan db.Person
dan kemudian menayangkan hasilnya ke dalam objek PersonDTO
. Dalam objek PersonDTO
, terdapat sifat personProtocol
yang ditetapkan kepada hasil pertanyaan LINQ terhadap koleksi ppCombined
.
Masalahnya cuba menggunakan ppCombined
sebagai nilai tetap dalam konteks pangkalan data. ppCombined
ialah objek IEnumerable
yang dibina dalam ingatan, bukan jadual pangkalan data. Apabila melaksanakan pertanyaan LINQ, ia cuba menukar unjuran personProtocol
kepada pernyataan SQL. Walau bagaimanapun, ia tidak boleh melakukan ini kerana ppCombined
bukan jadual pangkalan data atau jenis primitif.
Penyelesaian
Untuk menyelesaikan ralat ini, kami boleh mengambil item yang ditapis dalam ppCombined
dalam ingatan selepas mendapatkan semula atribut lain daripada pangkalan data. Berikut ialah kod yang diubah suai:
<code class="language-csharp">var persons = db.Favorites .Where(f => f.userId == userId) .Join(db.Person, f => f.personId, p => p.personId, (f, p) => new // 匿名对象 { personId = p.personId, addressId = p.addressId, favoriteId = f.favoriteId, }) .AsEnumerable() // 数据库查询在此结束,其余部分是在内存中进行的查询 .Select(x => new PersonDTO { personId = x.personId, addressId = x.addressId, favoriteId = x.favoriteId, personProtocol = ppCombined .Where(p => p.personId == x.personId) .Select(p => new PersonProtocol { personProtocolId = p.personProtocolId, activateDt = p.activateDt, personId = p.personId }) .ToList() });</code>
Dalam kod yang diubah suai ini, pertanyaan pangkalan data berakhir dengan kaedah AsEnumerable()
. Ini bermakna bahawa seluruh operasi dilakukan sepenuhnya dalam ingatan. Kemudian, dalam unjuran Select
berasaskan memori bagi objek tanpa nama, tapis koleksi ppCombined
dan tukarkannya kepada senarai.
Dengan mengasingkan pertanyaan pangkalan data daripada pemprosesan dalam memori, kami mengelakkan masalah menghantar koleksi dalam memori ke dalam konteks pangkalan data, sekali gus menyelesaikan pepijat.
Atas ialah kandungan terperinci Bagaimana untuk Menyelesaikan Ralat 'Tidak dapat mencipta nilai malar' dalam LINQ JOIN dengan IEnumerable Constant Collection?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!