Saya memiliki beberapa lonceng di database saya dengan nomor yang sama. Saya ingin mendapatkan semuanya tanpa duplikasi. Saya membuat kelas pembanding untuk melakukan pekerjaan ini, tetapi eksekusi fungsi menyebabkan penundaan besar dari fungsi tanpa perbedaan, dari 0,6 detik menjadi 3,2 detik!
Apakah saya melakukannya dengan benar atau apakah saya harus menggunakan metode lain?
reg.AddRange(
(from a in this.dataContext.reglements
join b in this.dataContext.Clients on a.Id_client equals b.Id
where a.date_v <= datefin && a.date_v >= datedeb
where a.Id_client == b.Id
orderby a.date_v descending
select new Class_reglement
{
nom = b.Nom,
code = b.code,
Numf = a.Numf,
})
.AsEnumerable()
.Distinct(new Compare())
.ToList());
class Compare : IEqualityComparer<Class_reglement>
{
public bool Equals(Class_reglement x, Class_reglement y)
{
if (x.Numf == y.Numf)
{
return true;
}
else { return false; }
}
public int GetHashCode(Class_reglement codeh)
{
return 0;
}
}
c#
linq
iequalitycomparer
Akrem
sumber
sumber
Jawaban:
GetHashCode
Penerapan Anda selalu menghasilkan nilai yang sama.Distinct
bergantung pada fungsi hash yang baik untuk bekerja secara efisien karena secara internal membangun tabel hash .Saat mengimplementasikan antarmuka kelas, penting untuk membaca dokumentasinya , untuk mengetahui kontrak mana yang harus Anda implementasikan. 1
Dalam kode Anda, solusinya adalah untuk meneruskan
GetHashCode
keClass_reglement.Numf.GetHashCode
dan menerapkannya tepat di sana.Selain itu,
Equals
metode Anda penuh dengan kode yang tidak perlu. Itu bisa ditulis ulang sebagai berikut (semantik yang sama, ¼ dari kode, lebih mudah dibaca):Terakhir,
ToList
panggilan tidak perlu dan memakan waktu:AddRange
menerima apa punIEnumerable
sehingga konversi ke aList
tidak diperlukan.AsEnumerable
adalah juga membazir di sini sejak pengolahan hasil diAddRange
akan menyebabkan ini pula.1 Menulis kode tanpa mengetahui apa yang sebenarnya dilakukannya disebut pemrograman kultus kargo . Ini adalah praktik yang sangat tersebar luas. Ini pada dasarnya tidak berhasil.
sumber
GetHashCode
. Namun, perhatikan bahwa dokumentasiIEqualityComparer<T>
tidak menentukan apa yang harus dilakukan dengannull
argumen - tetapi contoh yang diberikan dalam artikel juga tidak menanganinull
.Coba kode ini:
Contoh penggunaannya adalah
sumber
GetHashCode
perlu menggunakan ekspresi juga:return _expr.Invoke(obj).GetHashCode();
Lihat posting ini untuk penggunaan itu.Cukup kode, dengan implementasi
GetHashCode
danNULL
validasi:Contoh: daftar Class_reglement yang dibedakan oleh Numf
sumber
Dimasukkannya kelas perbandingan Anda (atau lebih khusus lagi
AsEnumerable
panggilan yang perlu Anda gunakan untuk membuatnya berfungsi) berarti bahwa logika pengurutan berubah dari yang berbasis pada server basis data menjadi pada klien basis data (aplikasi Anda). Ini berarti bahwa klien Anda sekarang perlu mengambil dan kemudian memproses data dalam jumlah yang lebih besar, yang akan selalu kurang efisien daripada melakukan pencarian di database tempat indeks yang sesuai dapat digunakan.Anda harus mencoba mengembangkan klausa where yang memenuhi persyaratan Anda, lihat Menggunakan IEqualityComparer dengan klausa LINQ ke Entitas Kecuali untuk detail selengkapnya.
sumber
Jika Anda menginginkan solusi umum tanpa tinju:
pemakaian:
sumber
IEquatable<T>
bisa menjadi cara yang jauh lebih mudah untuk melakukan ini dengan kerangka kerja modern.Anda mendapatkan
bool Equals(T other)
fungsi sederhana yang bagus dan tidak ada masalah dengan casting atau membuat kelas terpisah.Catatan Anda HARUS menerapkan
GetHashCode
jika menggunakan ini dalam kamus atau dengan sesuatu sepertiDistinct
.PS. Saya tidak berpikir ada metode Setara kustom yang bekerja dengan kerangka entitas langsung di sisi database (saya pikir Anda tahu ini karena Anda melakukan AsEnumerable) tetapi ini adalah metode yang jauh lebih sederhana untuk melakukan persamaan sederhana untuk kasus umum.
Jika hal-hal tampaknya tidak berfungsi (seperti kesalahan kunci duplikat saat melakukan ToDictionary) letakkan titik putus di dalam Sama dengan untuk memastikan itu terpukul dan pastikan Anda telah
GetHashCode
menentukan (dengan mengganti kata kunci).sumber
.Equals()
metode Anda tampaknya telah dibandingkanother.Hometown
dengan dirinya sendiri, alih-alihthis.Hometown