Try making the members in the anonymous type more obviously the same:
on new { Code = packagingMainCustom.ID_Code,
Version = packagingMainCustom.ID_Version }
equals new { Code = packagingMainSync.ID_Code,
Version = packagingMainSync.ID_CurrentVersion }
The main change here is that the names now match, as does the order, as presumably do the types; that means that these are actually now the same anonymous type in both places (anonymous types are essentially defined by the combination of member-names, order, type and declaring assembly).