LINQ باستثناء استخدام المقارن المخصص
-
06-07-2019 - |
سؤال
أحاول استخدام طريقة "باستثناء" في مجموعة نتائج LINQ باستخدام تطبيق مخصص إذا قام IEqualityComparer باستبعاد نتائج معينة بناءً على قيمة حقل واحد من مجموعة النتائج.
لذلك، في شكل مبسط لدي ...
'' Get collection of published sites...
Dim List1 = (From i In db.Sites _
Where (i.StatusID = published) _
Select i.SiteID, _
i.SiteName)
'' Find those with a pending site, but exclue all those whose SiteID is in List1...
Dim insComparer = New insCompare
Dim List2 = (From i In db.Sites _
Where (i.StatusID = pending) _
Select i.SiteID, _
i.SiteName).Except(List1, insComparer)
المقارن الخاص بي هو كما يلي ...
Public Class insCompare
Implements System.Collections.Generic.IEqualityComparer(Of Object)
Public Function Equals1(ByVal x As Object, ByVal y As Object) As Boolean Implements System.Collections.Generic.IEqualityComparer(Of Object).Equals
Return IIf(x.SiteID = y.SiteID, True, False)
End Function
Public Function GetHashCode1(ByVal x As Object) As Integer Implements System.Collections.Generic.IEqualityComparer(Of Object).GetHashCode
Return x.SiteID.ToString.ToLower.GetHashCode()
End Function
End Class
أحصل على استثناء إرسال غير صالح في السطر ".Except" مع الرسالة "غير قادر على إرسال كائن من النوع '...insCompare' لكتابة 'System.Collections.Generic.IEqualityComparer'"
هل يمكن لأي شخص أن يلقي الضوء على سبب ذلك من فضلك.
المحلول
مشكلتك هنا هي أنك تطبق IEqualityComparer(Of Object)، ولكن قوائمك هي List(Of AT) حيث AT هو نوع مجهول، لذلك لا يمكنك تطبيق IEqualityComparer(Of AT).
أعتقد أن اختياراتك هي:
- قم بتعريف فئة/بنية للاحتفاظ بـ SideID/SiteName، وحدد مثيلًا لتلك الفئة، ثم قم بتطبيق IEqualityComparer(Of NewClass).
- استخدم المكالمات المتأخرة (على سبيل المثال.تم إيقاف الخيار الصريح، كما يبدو أنك تفعل الآن)، وقم بإجراء استدعاء .Cast(Of Object)() على كلا القائمتين قبل الاتصال باستثناء.
نصائح أخرى
استخدم التعليمات البرمجية التالية.
from t in db.Sites
where
!
(from t0 in db.Sites2
select new {
t0.SomeID
}).Contains(new { t.SomeID })
select t
وهذا يوجد مقرها في ليست في حالة. أعتقد أن هذا سيساعدك. U به بعض الشيء المعقد.
ويبدو أنه يسأل أن المقارن الخاص بتطبيق واجهة IEqualityComparer
غير عام، في حين تنفذ لك IEqualityComparer (Of Object)
، وهو واجهة مختلفة.
يبدو أنك تستخدم قاعدة بيانات كواجهة خلفية.أنت لا أستطيع توفير مقارنة مخصصة لهذا، لأنه لا يمكن تعيينه إلى TSQL.
هل جربت Contains
؟أي. where !List1.Contains(i.SiteID)
?