When you read from a file by calling ReadLine, you take a line of text from the file, return it, and advance the pointer. So when you discard one of those lines each time you go round the loop by reading a line and checking if it is null, you are both getting out of step, and running out of file.
Suppose your file contains
The entry to your loop reads and discards "Name1", then puts "Surname1" into the Name field, "Address1" into teh Surname feild, "Preference1" into the Address field, and "Name2" into the Preference field.
Change the Loop condition:
while (tr.Peek() >= 0)