I am trying to learn the Linq/Lambda
expressions and was stuck at somewhere.
What I was Doing
I have created two classes with
Public Class dosyalar
Public adi As String
Public tarih As DateTime
End Class
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim dosyalarList1 As New List(Of dosyalar)
dosyalarList1.Add(New dosyalar With {.adi = "dosya1", .tarih = New DateTime(2020, 3, 30, 10, 10, 10)})
dosyalarList1.Add(New dosyalar With {.adi = "dosya2", .tarih = New DateTime(2020, 3, 30, 10, 10, 20)})
dosyalarList1.Add(New dosyalar With {.adi = "dosya3", .tarih = New DateTime(2020, 3, 30, 10, 10, 30)})
dosyalarList1.Add(New dosyalar With {.adi = "dosya4", .tarih = New DateTime(2020, 3, 30, 10, 10, 40)})
dosyalarList1.Add(New dosyalar With {.adi = "dosya5", .tarih = New DateTime(2020, 3, 30, 10, 10, 50)})
Dim dosyalarList2 As New List(Of dosyalar)
dosyalarList2.Add(New dosyalar With {.adi = "dosya1", .tarih = New DateTime(2020, 3, 30, 10, 10, 11)})
dosyalarList2.Add(New dosyalar With {.adi = "dosya2", .tarih = New DateTime(2020, 3, 30, 10, 10, 21)})
dosyalarList2.Add(New dosyalar With {.adi = "dosya3", .tarih = New DateTime(2020, 3, 30, 10, 10, 30)})
dosyalarList2.Add(New dosyalar With {.adi = "dosya4", .tarih = New DateTime(2020, 3, 30, 10, 10, 40)})
dosyalarList2.Add(New dosyalar With {.adi = "dosya5", .tarih = New DateTime(2020, 3, 30, 10, 10, 50)})
Dim result As List(Of dosyalar) = dosyalarList1.Where(Function(a) Not dosyalarList2.Any(Function(b) a.adi = b.adi AndAlso a.tarih = b.tarih)).ToList
End Sub
You have said that you need only these objects from testListA
:
ProductID
in testListB
ProductID
, but with different Category
So, your filter must be:
!testListB.Any(b => a.ProductID == b.ProductID && a.Category == b.Category)
So, change your code as:
testListA.Where(a => !testListB.Any(b => a.ProductID == b.ProductID && a.Category == b.Category));
Second approach:
Or you can create a new List<TestA>
from the second list:
var secondListA = testListB.Select(x=> new TestA(){Category=x.Category, ProductID=x.ProductID}).ToList();
And then create your Comparer
:
sealed class MyComparer : IEqualityComparer<TestA>
{
public bool Equals(TestA x, TestA y)
{
if (x == null)
return y == null;
else if (y == null)
return false;
else
return x.ProductID == y.ProductID && x.Category == y.Category;
}
public int GetHashCode(TestA obj)
{
return obj.ProductID.GetHashCode();
}
}
And use Except() overload which produces the set difference of two sequences by using the specified IEqualityComparer<T>
to compare values.:
var result = testListA.Except(secondListA, new MyComparer ()).ToList();
This is an example implementing IEqualityComparer. It should work as a concept for your purpose:
private class PKExclusiveComparer<T> : IEqualityComparer<T> where T : DataRow
{
public bool Equals(T x, T y)
{
bool result = true;
foreach (DataColumn col in (x as DataRow).Table.Columns)
{
if (!(x as DataRow).Table.PrimaryKey.Contains(col))
{
result &= x[col].Equals(y[col]);
}
}
return result;
}
public int GetHashCode(T x)
{
string code = string.Empty;
foreach (DataColumn col in (x as DataRow).Table.Columns)
{
if (!(x as DataRow).Table.PrimaryKey.Contains(col))
{
code += x[col].ToString();
}
}
return code.GetHashCode();
}
}