Dalam kueri ini:
public static IEnumerable<IServerOnlineCharacter> GetUpdated()
{
var context = DataContext.GetDataContext();
return context.ServerOnlineCharacters
.OrderBy(p => p.ServerStatus.ServerDateTime)
.GroupBy(p => p.RawName)
.Select(p => p.Last());
}
Saya harus beralih ke ini agar bisa berfungsi
public static IEnumerable<IServerOnlineCharacter> GetUpdated()
{
var context = DataContext.GetDataContext();
return context.ServerOnlineCharacters
.OrderByDescending(p => p.ServerStatus.ServerDateTime)
.GroupBy(p => p.RawName)
.Select(p => p.FirstOrDefault());
}
Saya bahkan tidak bisa menggunakan p.First()
, untuk mencerminkan permintaan pertama.
Mengapa ada batasan dasar seperti itu dalam apa yang sebaliknya sistem ORM yang kuat?
c#
entity-framework
orm
bevacqua
sumber
sumber
Jawaban:
Keterbatasan itu bermuara pada kenyataan bahwa pada akhirnya ia harus menerjemahkan permintaan itu ke SQL dan SQL memiliki
SELECT TOP
(dalam T-SQL) tetapi bukanSELECT BOTTOM
(tidak ada hal seperti itu).Namun ada cara mudah untuk itu, hanya memesan turun dan kemudian melakukan
First()
, yang adalah apa yang Anda lakukan.EDIT: Penyedia lain mungkin akan memiliki implementasi yang berbeda
SELECT TOP 1
, di Oracle mungkin akan menjadi sesuatu yang lebih sepertiWHERE ROWNUM = 1
EDIT:
Alternatif lain yang kurang efisien - Saya TIDAK merekomendasikan ini! - adalah untuk memanggil
.ToList()
data Anda sebelumnya.Last()
, yang akan segera menjalankan Ekspresi LINQ To Entities yang telah dibangun hingga saat itu, dan kemudian .Last () Anda akan berfungsi, karena pada saat.Last()
itu dieksekusi secara efektif dalam konteks LINQ ke Objects Expression. (Dan seperti yang Anda tunjukkan, itu bisa mengembalikan ribuan catatan dan membuang banyak objek pematerialan CPU yang tidak akan pernah digunakan)Sekali lagi, saya tidak akan merekomendasikan melakukan hal ini, tetapi itu membantu menggambarkan perbedaan antara di mana dan kapan ekspresi LINQ dieksekusi.
sumber
ToList
tidak terlalu buruk.Alih-alih
Last()
, Coba ini:sumber
Ganti
Last()
oleh pemilih LinqOrderByDescending(x => x.ID).Take(1).Single()
Sesuatu seperti itu akan berhasil jika Anda lebih suka melakukannya di Linq:
sumber
Namun cara lain mendapatkan elemen terakhir tanpa OrderByDescending dan memuat semua entitas:
sumber
Itu karena LINQ ke Entitas (dan basis data secara umum) tidak mendukung semua metode LINQ (lihat di sini untuk detail: http://msdn.microsoft.com/en-us/library/bb738550.aspx )
Yang Anda butuhkan di sini adalah memesan data sedemikian rupa sehingga catatan "terakhir" menjadi "pertama" dan kemudian Anda dapat menggunakan FirstOrDefault. Perhatikan bahwa databasese biasanya tidak memiliki konsep seperti "pertama" dan "terakhir", tidak seperti catatan yang paling baru disisipkan akan "terakhir" dalam tabel.
Metode ini dapat menyelesaikan masalah Anda
sumber
Menambahkan fungsi tunggal
AsEnumerable()
sebelum fungsi Pilih bekerja untuk saya.Contoh:
Ref: https://www.codeproject.com/Questions/1005274/LINQ-to-Entities-does-not-recognize-the-method-Sys
sumber