How best to join tables, which have different lengths on the same column values which exist in both tables?

I think you should stay away from associations because your keys aren't unique. Maybe just go over all tuples of elements and pick those that match your criterion:

Reap[Outer[If[#1[[1]] == #2[[1]], Sow@Join@##] &, TableOne, TableTwo, 1]][[2, 1]]

(*    {{a, x1, a, y1}, {a, x1, a, y3}, {a, x1, a, y4}, {b, x2, b, y5}, {c, x3, c, y2},
       {c, x3, c, y6}, {c, x3, c, y7}}    *)

Alternatively, construct a list of all tuples and then select: (this may use more memory if the lists are large)

Flatten /@ Select[Tuples[{TableOne, TableTwo}], #[[1, 1]] == #[[2, 1]] &]

(*    {{a, x1, a, y1}, {a, x1, a, y3}, {a, x1, a, y4}, {b, x2, b, y5}, {c, x3, c, y2},
       {c, x3, c, y6}, {c, x3, c, y7}}    *)

assocOne = AssociationThread[First /@ #, #] & @ TableOne;

f = Join[assocOne[First @ #], #]&;

Map[f] @ TableTwo  

{{a, x1, a, y1}, {c, x3, c, y2}, {a, x1, a, y3}, {a, x1, a, y4}, {b, x2, b, y5}, {c, x3, c, y6}, {c, x3, c, y7}}


Flatten[Table[Join[n, #] & /@ Cases[TableTwo, {n[[1]], _}], {n, TableOne}], 1]

  (* {{a, x1, a, y1}, {a, x1, a, y3}, {a, x1, a, y4}, {b, x2, b, y5}, {c, 
  x3, c, y2}, {c, x3, c, y6}, {c, x3, c, y7}} *)