Dalam hal ini penting untuk membedakan antara IQueryable<T>
dan IEnumerable<T>
. Singkatnya IQueryable<T>
diproses oleh penyedia LINQ untuk mengirimkan permintaan yang dioptimalkan. Selama transformasi ini tidak semua pernyataan C # didukung, karena tidak mungkin menerjemahkannya ke kueri spesifik back-end (misalnya SQL) atau karena pelaksana tidak melihat kebutuhan akan pernyataan tersebut.
Sebaliknya IEnumerable<T>
dieksekusi terhadap benda konkret dan, oleh karena itu, tidak akan diubah. Jadi, sangat umum bahwa konstruksi, yang dapat digunakan dengan IEnumerable<T>
, tidak dapat digunakan dengan IQueryable<T>
dan juga yang IQueryables<T>
didukung oleh penyedia LINQ yang berbeda tidak mendukung serangkaian fungsi yang sama.
Namun, ada beberapa solusi (seperti jawaban Phil ), yang mengubah kueri. Juga, sebagai pendekatan yang lebih umum dimungkinkan untuk kembali ke IEnumerable<T>
sebelum melanjutkan dengan spesifikasi permintaan. Namun, ini mungkin memiliki hit kinerja - terutama ketika menggunakannya pada pembatasan (misalnya di mana klausa). Sebaliknya, ketika berhadapan dengan transformasi, hit kinerja jauh lebih kecil, kadang-kadang bahkan tidak ada - tergantung pada permintaan Anda.
Jadi kode di atas juga bisa ditulis ulang seperti ini:
return this.ObjectContext.BranchCostDetails
.AsEnumerable()
.Where(
b => b.TarrifId == tariffId && b.Diameter == diameter
|| (b.TarrifId==tariffId && !string.IsNullOrWhiteSpace(b.Diameter))
||(!b.TarrifId.HasValue) && b.Diameter==diameter
);
CATATAN: Kode THS akan memiliki dampak kinerja yang lebih tinggi daripada jawaban Phil . Namun, itu menunjukkan prinsipnya.
List<string> my = new List<string>(); var i = from m in my where !string.IsNullOrWhiteSpace(m) select m;