Conjecturaly speaking, you will want to make your selections first and then intersect them. So, in SQL, you would do it this way:
SELECT
A.ColumnA,
A.ColumnB,
A.ColumnC,
A.ColumnD
FROM tableA AS A
INNER JOIN tableB AS B
ON A.ColumnA = B.ColumnA
AND A.ColumnB = B.ColumnB
AND A.ColumnC = B.ColumnC
WHERE A.ColumnD = 1
The problem is that this is difficult to represent using Lambdas with DataEntity classes, mostly because it is hard to shape the dynamic SQL the ORM creates on the fly. So you go for the next best thing.
You select your first entity list from tableA:
var studentsA = MyStudentEntitiesA
.Where(a => a.ColumnD == 1);
You select your second entity from tableB:
var studentsB = MyStudentEntitiesB
.Where(b => studentsA.Any(a =>
a.ColumnA == b.ColumnA &&
a.ColumnB == b.ColumnB &&
a.ColumnC == b.ColumnC)
);
And now you can do your foreach statement:
foreach (var b in studentsB)
{
Console.WriteLine($"ColumnA:{b.ColumnA}, ColumnB:{b.ColumnB}, ColumnC:{b.ColumnC}");
}