Saya memiliki dua ekspresi tipe Expression<Func<T, bool>>
dan saya ingin mengambil OR, DAN atau TIDAK dari ini dan mendapatkan ekspresi baru dari tipe yang sama
Expression<Func<T, bool>> expr1;
Expression<Func<T, bool>> expr2;
...
//how to do this (the code below will obviously not work)
Expression<Func<T, bool>> andExpression = expr AND expr2
c#
linq
lambda
expression
BjartN
sumber
sumber
Jawaban:
Nah, Anda bisa menggunakan
Expression.AndAlso
/OrElse
etc untuk menggabungkan ekspresi logis, tetapi masalahnya adalah parameternya; apakah Anda bekerja dengan yang samaParameterExpression
di expr1 dan expr2? Jika demikian, lebih mudah:Ini juga berfungsi dengan baik untuk meniadakan satu operasi:
Jika tidak, tergantung pada penyedia LINQ, Anda mungkin dapat menggabungkannya dengan
Invoke
:Di suatu tempat, saya sudah mendapatkan beberapa kode yang menulis ulang pohon ekspresi-menggantikan node untuk menghapus kebutuhan
Invoke
, tetapi itu cukup panjang (dan saya tidak ingat di mana saya meninggalkannya ...)Versi umum yang memilih rute paling sederhana:
Mulai dari .NET 4.0, ada
ExpressionVisitor
kelas yang memungkinkan Anda untuk membangun ekspresi yang aman EF.sumber
ExpressionVisitor
) tidak ada saat itu; Saya punya contoh terkait pada stackoverflow dari tanggal yang sama di mana ia mengimplementasikan pengunjung secara manual: banyak kode.Anda dapat menggunakan Expression.AndAlso / OrElse untuk menggabungkan ekspresi logis, tetapi Anda harus memastikan ParameterExpressions adalah sama.
Saya mengalami masalah dengan EF dan PredicateBuilder sehingga saya membuatnya sendiri tanpa menggunakan Invoke, yang dapat saya gunakan seperti ini:
Kode sumber untuk PredicateBuilder saya:
Dan kelas utilitas untuk mengganti parameter dalam lambda:
sumber
Jika penyedia Anda tidak mendukung Invoke dan Anda perlu menggabungkan dua ekspresi, Anda bisa menggunakan ExpressionVisitor untuk mengganti parameter dalam ekspresi kedua dengan parameter dalam ekspresi pertama.
sumber
Tidak ada yang baru di sini selain menikahi jawaban ini dengan jawaban ini dan sedikit refactored sehingga bahkan saya mengerti apa yang terjadi:
sumber
Saya perlu mencapai hasil yang sama, tetapi menggunakan sesuatu yang lebih umum (karena jenisnya tidak diketahui). Berkat jawaban Marc, akhirnya saya menemukan apa yang saya coba capai:
sumber
Saya menyarankan satu peningkatan lagi ke PredicateBuilder dan
ExpressionVisitor
solusi. Saya menyebutnyaUnifyParametersByName
dan Anda dapat menemukannya di perpustakaan MIT saya: LinqExprHelper . Hal ini memungkinkan untuk menggabungkan ekspresi lambda arbiter. Biasanya pertanyaan diajukan tentang ekspresi predikat, tetapi ide ini meluas ke ekspresi proyeksi juga.Kode berikut menggunakan metode
ExprAdres
yang menciptakan ekspresi parametrized yang rumit, menggunakan inline lambda. Ekspresi rumit ini dikodekan hanya sekali, dan kemudian digunakan kembali, berkatLinqExprHelper
perpustakaan mini.Dan ini adalah kode bangunan subekspresi:
Apa yang saya coba capai adalah melakukan query parametrized tanpa perlu copy-paste dan dengan kemampuan untuk menggunakan lambda inline, yang sangat cantik. Tanpa semua hal pembantu-ekspresi ini, saya akan dipaksa untuk membuat seluruh permintaan dalam sekali jalan.
sumber
Saya pikir ini berfungsi dengan baik, bukan?
sumber